From 8afc0844aa49705c3c48c9e093ee6b749c442a3e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 11:25:24 +0200 Subject: [PATCH 01/17] musl: revert Emscripten-specific changes This is an automatic change generated with: ``` ./system/lib/update_musl.py ~/Downloads/musl-1.2.5 ``` --- .../libc/musl/arch/emscripten/atomic_arch.h | 111 ---- .../libc/musl/arch/emscripten/bits/alltypes.h | 481 ------------------ .../musl/arch/emscripten/bits/alltypes.h.in | 43 -- .../libc/musl/arch/emscripten/bits/endian.h | 1 - .../libc/musl/arch/emscripten/bits/errno.h | 144 ------ .../lib/libc/musl/arch/emscripten/bits/fenv.h | 27 - .../libc/musl/arch/emscripten/bits/float.h | 17 - .../libc/musl/arch/emscripten/bits/limits.h | 1 - .../libc/musl/arch/emscripten/bits/posix.h | 2 - .../lib/libc/musl/arch/emscripten/bits/reg.h | 6 - .../libc/musl/arch/emscripten/bits/setjmp.h | 1 - .../libc/musl/arch/emscripten/bits/signal.h | 123 ----- .../lib/libc/musl/arch/emscripten/bits/stat.h | 26 - .../libc/musl/arch/emscripten/bits/syscall.h | 89 ---- .../lib/libc/musl/arch/emscripten/bits/user.h | 48 -- .../lib/libc/musl/arch/emscripten/crt_arch.h | 0 system/lib/libc/musl/arch/emscripten/kstat.h | 3 - .../libc/musl/arch/emscripten/pthread_arch.h | 5 - .../libc/musl/arch/emscripten/syscall_arch.h | 8 - .../lib/libc/musl/arch/generic/bits/stdarg.h | 4 - system/lib/libc/musl/config.mak | 32 -- system/lib/libc/musl/configure | 4 +- system/lib/libc/musl/include/alltypes.h.in | 35 +- system/lib/libc/musl/include/fcntl.h | 10 - system/lib/libc/musl/include/features.h | 7 - system/lib/libc/musl/include/inttypes.h | 7 +- system/lib/libc/musl/include/limits.h | 7 - system/lib/libc/musl/include/locale.h | 2 +- system/lib/libc/musl/include/setjmp.h | 6 - system/lib/libc/musl/include/signal.h | 2 +- system/lib/libc/musl/include/stddef.h | 2 +- system/lib/libc/musl/include/stdint.h | 185 ++++--- system/lib/libc/musl/include/stdio.h | 12 +- system/lib/libc/musl/include/stdlib.h | 2 +- system/lib/libc/musl/include/string.h | 2 +- system/lib/libc/musl/include/time.h | 2 +- system/lib/libc/musl/include/unistd.h | 40 +- system/lib/libc/musl/include/wchar.h | 2 +- system/lib/libc/musl/src/conf/confstr.c | 19 - system/lib/libc/musl/src/conf/fpathconf.c | 2 +- system/lib/libc/musl/src/conf/sysconf.c | 35 +- system/lib/libc/musl/src/dirent/opendir.c | 4 - system/lib/libc/musl/src/env/__environ.c | 37 -- .../lib/libc/musl/src/env/__stack_chk_fail.c | 5 - .../libc/musl/src/errno/__errno_location.c | 11 - system/lib/libc/musl/src/errno/__strerror.h | 17 +- system/lib/libc/musl/src/errno/strerror.c | 16 - system/lib/libc/musl/src/exit/_Exit.c | 4 - system/lib/libc/musl/src/exit/abort.c | 13 - system/lib/libc/musl/src/exit/atexit.c | 14 +- system/lib/libc/musl/src/fcntl/fcntl.c | 32 +- system/lib/libc/musl/src/fcntl/open.c | 2 - system/lib/libc/musl/src/internal/atomic.h | 2 +- system/lib/libc/musl/src/internal/dynlink.h | 36 -- system/lib/libc/musl/src/internal/libc.c | 2 - system/lib/libc/musl/src/internal/libc.h | 6 - system/lib/libc/musl/src/internal/libm.h | 8 - .../lib/libc/musl/src/internal/locale_impl.h | 16 - system/lib/libc/musl/src/internal/progname.c | 37 -- .../internal/proxying_notification_state.h | 18 - .../lib/libc/musl/src/internal/pthread_impl.h | 92 +--- .../lib/libc/musl/src/internal/stdio_impl.h | 16 +- system/lib/libc/musl/src/internal/syscall.h | 54 +- system/lib/libc/musl/src/linux/gettid.c | 28 - system/lib/libc/musl/src/linux/sbrk.c | 3 - system/lib/libc/musl/src/linux/statx.c | 4 - system/lib/libc/musl/src/locale/catclose.c | 2 - system/lib/libc/musl/src/locale/catgets.c | 6 - system/lib/libc/musl/src/locale/catopen.c | 4 - system/lib/libc/musl/src/locale/dcngettext.c | 2 +- system/lib/libc/musl/src/locale/iconv.c | 6 +- system/lib/libc/musl/src/locale/locale_map.c | 4 - system/lib/libc/musl/src/locale/uselocale.c | 11 - .../lib/libc/musl/src/malloc/reallocarray.c | 17 - system/lib/libc/musl/src/math/ceil.c | 8 - system/lib/libc/musl/src/math/ceilf.c | 6 - system/lib/libc/musl/src/math/copysign.c | 6 - system/lib/libc/musl/src/math/copysignf.c | 6 - system/lib/libc/musl/src/math/fabs.c | 6 - system/lib/libc/musl/src/math/fabsf.c | 6 - system/lib/libc/musl/src/math/floor.c | 8 - system/lib/libc/musl/src/math/floorf.c | 6 - system/lib/libc/musl/src/math/fma.c | 2 - system/lib/libc/musl/src/math/fmaf.c | 2 - system/lib/libc/musl/src/math/fmal.c | 2 - system/lib/libc/musl/src/math/fmax.c | 5 - system/lib/libc/musl/src/math/fmaxf.c | 5 - system/lib/libc/musl/src/math/fmin.c | 5 - system/lib/libc/musl/src/math/fminf.c | 5 - system/lib/libc/musl/src/math/ilogb.c | 2 - system/lib/libc/musl/src/math/ilogbf.c | 2 - system/lib/libc/musl/src/math/ilogbl.c | 4 - system/lib/libc/musl/src/math/log2_small.c | 122 ----- system/lib/libc/musl/src/math/log_small.c | 118 ----- system/lib/libc/musl/src/math/pow_small.c | 328 ------------ system/lib/libc/musl/src/math/rint.c | 8 - system/lib/libc/musl/src/math/rintf.c | 8 - system/lib/libc/musl/src/math/sqrt.c | 8 - system/lib/libc/musl/src/math/sqrtf.c | 8 - system/lib/libc/musl/src/math/sqrtl.c | 4 - system/lib/libc/musl/src/math/trunc.c | 6 - system/lib/libc/musl/src/math/truncf.c | 6 - system/lib/libc/musl/src/misc/getentropy.c | 8 - system/lib/libc/musl/src/misc/getopt.c | 2 +- system/lib/libc/musl/src/misc/ioctl.c | 5 - system/lib/libc/musl/src/mman/mmap.c | 1 - system/lib/libc/musl/src/mman/munmap.c | 1 - .../lib/libc/musl/src/multibyte/mbsrtowcs.c | 6 +- .../lib/libc/musl/src/network/freeaddrinfo.c | 8 - .../libc/musl/src/network/if_indextoname.c | 4 - .../libc/musl/src/network/if_nametoindex.c | 4 - system/lib/libc/musl/src/network/netlink.c | 4 - system/lib/libc/musl/src/network/ns_parse.c | 60 +-- system/lib/libc/musl/src/network/recvmmsg.c | 2 +- system/lib/libc/musl/src/network/recvmsg.c | 4 +- system/lib/libc/musl/src/network/res_msend.c | 8 - system/lib/libc/musl/src/network/sendmsg.c | 2 +- system/lib/libc/musl/src/process/fexecve.c | 2 - system/lib/libc/musl/src/sched/sched_yield.c | 14 - system/lib/libc/musl/src/select/ppoll.c | 11 - system/lib/libc/musl/src/select/pselect.c | 15 - system/lib/libc/musl/src/select/select.c | 85 +--- system/lib/libc/musl/src/signal/block.c | 6 - system/lib/libc/musl/src/signal/getitimer.c | 11 - system/lib/libc/musl/src/signal/setitimer.c | 116 ----- system/lib/libc/musl/src/stat/fchmod.c | 8 - system/lib/libc/musl/src/stat/fchmodat.c | 10 - system/lib/libc/musl/src/stat/fstatat.c | 18 - system/lib/libc/musl/src/stdio/__fdopen.c | 2 - .../lib/libc/musl/src/stdio/__fopen_rb_ca.c | 2 - system/lib/libc/musl/src/stdio/__lockfile.c | 6 +- .../lib/libc/musl/src/stdio/__stdio_close.c | 4 - system/lib/libc/musl/src/stdio/__stdio_read.c | 8 - .../lib/libc/musl/src/stdio/__stdio_write.c | 8 - system/lib/libc/musl/src/stdio/fopen.c | 6 - system/lib/libc/musl/src/stdio/fprintf.c | 22 - system/lib/libc/musl/src/stdio/freopen.c | 2 - system/lib/libc/musl/src/stdio/getc.h | 2 +- system/lib/libc/musl/src/stdio/printf.c | 23 - system/lib/libc/musl/src/stdio/putc.h | 2 +- system/lib/libc/musl/src/stdio/sprintf.c | 23 - system/lib/libc/musl/src/stdio/stdout.c | 21 - system/lib/libc/musl/src/stdio/tmpfile.c | 4 - system/lib/libc/musl/src/stdio/vfprintf.c | 101 +--- system/lib/libc/musl/src/stdio/vsnprintf.c | 55 -- system/lib/libc/musl/src/stdio/vsprintf.c | 13 - system/lib/libc/musl/src/stdlib/strtol.c | 84 --- system/lib/libc/musl/src/string/memchr.c | 3 +- system/lib/libc/musl/src/string/memcmp.c | 24 - system/lib/libc/musl/src/string/stpcpy.c | 4 +- system/lib/libc/musl/src/string/stpncpy.c | 5 +- system/lib/libc/musl/src/string/strchrnul.c | 4 +- system/lib/libc/musl/src/string/strlen.c | 3 +- system/lib/libc/musl/src/temp/__randname.c | 5 - system/lib/libc/musl/src/thread/__timedwait.c | 20 - system/lib/libc/musl/src/thread/__wait.c | 9 - .../lib/libc/musl/src/thread/pthread_atfork.c | 6 - .../libc/musl/src/thread/pthread_attr_get.c | 8 +- .../musl/src/thread/pthread_barrier_wait.c | 11 +- .../lib/libc/musl/src/thread/pthread_cancel.c | 16 +- .../musl/src/thread/pthread_cond_timedwait.c | 17 - .../src/thread/pthread_condattr_setpshared.c | 3 - .../lib/libc/musl/src/thread/pthread_detach.c | 18 - .../libc/musl/src/thread/pthread_getattr_np.c | 5 - .../musl/src/thread/pthread_getconcurrency.c | 2 - .../musl/src/thread/pthread_getcpuclockid.c | 5 - .../musl/src/thread/pthread_getschedparam.c | 5 - .../lib/libc/musl/src/thread/pthread_join.c | 37 -- .../libc/musl/src/thread/pthread_key_create.c | 4 - .../libc/musl/src/thread/pthread_mutex_lock.c | 3 - .../musl/src/thread/pthread_mutex_timedlock.c | 16 - .../musl/src/thread/pthread_mutex_trylock.c | 16 +- .../musl/src/thread/pthread_mutex_unlock.c | 4 - .../thread/pthread_mutexattr_setprotocol.c | 2 - .../src/thread/pthread_mutexattr_setpshared.c | 3 - .../src/thread/pthread_mutexattr_setrobust.c | 2 - .../src/thread/pthread_rwlock_timedwrlock.c | 14 +- .../src/thread/pthread_rwlock_trywrlock.c | 5 - .../musl/src/thread/pthread_rwlock_unlock.c | 6 - .../thread/pthread_rwlockattr_setpshared.c | 3 - .../musl/src/thread/pthread_setconcurrency.c | 2 - .../musl/src/thread/pthread_setschedparam.c | 5 - .../musl/src/thread/pthread_setschedprio.c | 5 - system/lib/libc/musl/src/thread/sem_init.c | 3 - .../lib/libc/musl/src/thread/sem_timedwait.c | 3 - system/lib/libc/musl/src/thread/thrd_create.c | 9 - system/lib/libc/musl/src/thread/thrd_join.c | 6 +- system/lib/libc/musl/src/thread/thrd_yield.c | 2 - system/lib/libc/musl/src/time/__map_file.c | 4 - system/lib/libc/musl/src/time/__tz.c | 33 +- system/lib/libc/musl/src/time/clock_getres.c | 15 - system/lib/libc/musl/src/time/clock_gettime.c | 19 - .../lib/libc/musl/src/time/clock_nanosleep.c | 23 - system/lib/libc/musl/src/time/clock_settime.c | 9 - system/lib/libc/musl/src/time/localtime_r.c | 6 - system/lib/libc/musl/src/time/strftime.c | 6 - system/lib/libc/musl/src/unistd/close.c | 6 - system/lib/libc/musl/src/unistd/dup2.c | 7 - system/lib/libc/musl/src/unistd/faccessat.c | 6 - system/lib/libc/musl/src/unistd/fchdir.c | 8 - system/lib/libc/musl/src/unistd/fchown.c | 10 +- system/lib/libc/musl/src/unistd/fsync.c | 4 - system/lib/libc/musl/src/unistd/isatty.c | 21 - system/lib/libc/musl/src/unistd/lseek.c | 5 - system/lib/libc/musl/src/unistd/pipe2.c | 2 - system/lib/libc/musl/src/unistd/pread.c | 12 - system/lib/libc/musl/src/unistd/preadv.c | 8 - system/lib/libc/musl/src/unistd/pwrite.c | 12 - system/lib/libc/musl/src/unistd/pwritev.c | 8 - system/lib/libc/musl/src/unistd/read.c | 12 - system/lib/libc/musl/src/unistd/readv.c | 8 - system/lib/libc/musl/src/unistd/setxid.c | 9 +- system/lib/libc/musl/src/unistd/write.c | 12 - system/lib/libc/musl/src/unistd/writev.c | 11 - system/lib/libc/musl/tools/mkalltypes.sed | 15 - 215 files changed, 218 insertions(+), 3985 deletions(-) delete mode 100644 system/lib/libc/musl/arch/emscripten/atomic_arch.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/alltypes.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/endian.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/errno.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/fenv.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/float.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/limits.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/posix.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/reg.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/setjmp.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/signal.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/stat.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/syscall.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/user.h delete mode 100644 system/lib/libc/musl/arch/emscripten/crt_arch.h delete mode 100644 system/lib/libc/musl/arch/emscripten/kstat.h delete mode 100644 system/lib/libc/musl/arch/emscripten/pthread_arch.h delete mode 100644 system/lib/libc/musl/arch/emscripten/syscall_arch.h delete mode 100644 system/lib/libc/musl/arch/generic/bits/stdarg.h delete mode 100644 system/lib/libc/musl/config.mak delete mode 100644 system/lib/libc/musl/src/internal/progname.c delete mode 100644 system/lib/libc/musl/src/internal/proxying_notification_state.h delete mode 100644 system/lib/libc/musl/src/malloc/reallocarray.c delete mode 100644 system/lib/libc/musl/src/math/log2_small.c delete mode 100644 system/lib/libc/musl/src/math/log_small.c delete mode 100644 system/lib/libc/musl/src/math/pow_small.c delete mode 100644 system/lib/libc/musl/tools/mkalltypes.sed diff --git a/system/lib/libc/musl/arch/emscripten/atomic_arch.h b/system/lib/libc/musl/arch/emscripten/atomic_arch.h deleted file mode 100644 index 937fd43fc97e2..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/atomic_arch.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _INTERNAL_ATOMIC_H -#define _INTERNAL_ATOMIC_H - -#include - -#define a_clz_l __builtin_clz -#define a_ctz_l __builtin_ctz -#define a_clz_64 __builtin_clzll -#define a_ctz_64 __builtin_ctzll - -#define a_and_64 a_and_64 -static inline void a_and_64(volatile uint64_t *p, uint64_t v) -{ - *p &= v; -} - -#define a_or_64 a_or_64 -static inline void a_or_64(volatile uint64_t *p, uint64_t v) -{ - *p |= v; -} - -#define a_store_l a_store_l -static inline void a_store_l(volatile void *p, long x) -{ - __c11_atomic_store((_Atomic long*)p, x, __ATOMIC_SEQ_CST); -} - -#define a_or_l a_or_l -static inline void a_or_l(volatile void *p, long v) -{ - __c11_atomic_fetch_or((_Atomic long*)p, v, __ATOMIC_SEQ_CST); -} -#define a_cas_p a_cas_p -static inline void *a_cas_p(volatile void *p, void *t, void *s) -{ - uintptr_t expected = (uintptr_t)t; - __c11_atomic_compare_exchange_strong((_Atomic uintptr_t*)p, &expected, (uintptr_t)s, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return (void*)expected; -} - -#define a_cas_l a_cas_l -static inline long a_cas_l(volatile void *p, long t, long s) -{ - long expected = t; - __c11_atomic_compare_exchange_strong((_Atomic long*)p, &expected, s, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return expected; -} - -#define a_cas a_cas -static inline int a_cas(volatile int *p, int t, int s) -{ - int expected = t; - __c11_atomic_compare_exchange_strong((_Atomic int*)p, &expected, s, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return expected; -} - -#define a_or a_or -static inline void a_or(volatile void *p, int v) -{ - __c11_atomic_fetch_or((_Atomic int*)p, v, __ATOMIC_SEQ_CST); -} - -#define a_and a_and -static inline void a_and(volatile void *p, int v) -{ - __c11_atomic_fetch_and((_Atomic int*)p, v, __ATOMIC_SEQ_CST); -} - -#define a_swap a_swap -static inline int a_swap(volatile int *x, int v) -{ - return __c11_atomic_exchange((_Atomic int*)x, v, __ATOMIC_SEQ_CST); -} - -#define a_fetch_add a_fetch_add -static inline int a_fetch_add(volatile int *x, int v) -{ - return __c11_atomic_fetch_add((_Atomic int*)x, v, __ATOMIC_SEQ_CST); -} - -#define a_inc a_inc -static inline void a_inc(volatile int *x) -{ - __c11_atomic_fetch_add((_Atomic int*)x, 1, __ATOMIC_SEQ_CST); -} - -#define a_dec a_dec -static inline void a_dec(volatile int *x) -{ - __c11_atomic_fetch_sub((_Atomic int*)x, 1, __ATOMIC_SEQ_CST); -} - -#define a_store a_store -static inline void a_store(volatile int *p, int x) -{ - __c11_atomic_store((_Atomic int*)p, x, __ATOMIC_SEQ_CST); -} - -#define a_spin a_spin -static inline void a_spin() -{ -} - -#define a_crash a_crash -static inline void a_crash() -{ - __builtin_trap(); -} - -#endif diff --git a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h deleted file mode 100644 index 0db4d998f29c8..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h +++ /dev/null @@ -1,481 +0,0 @@ -/* - * The .h version of this file is generated from the .h.in. - * See update_alltypes.sh. - */ -#define _Addr __PTRDIFF_TYPE__ -#define _Int64 __INT64_TYPE__ -#define _Reg __PTRDIFF_TYPE__ - -#define __BYTE_ORDER 1234 -#define __LONG_MAX __LONG_MAX__ - -#ifndef __cplusplus -#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) -typedef __WCHAR_TYPE__ wchar_t; -#define __DEFINED_wchar_t -#endif - -#endif -#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) -typedef __WINT_TYPE__ wint_t; -#define __DEFINED_wint_t -#endif - - -// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 -#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) -typedef int blkcnt_t; -#define __DEFINED_blkcnt_t -#endif - -#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) -typedef int blksize_t; -#define __DEFINED_blksize_t -#endif - -#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) -typedef int clock_t; -#define __DEFINED_clock_t -#endif - -#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) -typedef unsigned int dev_t; -#define __DEFINED_dev_t -#endif - -#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) -typedef int suseconds_t; -#define __DEFINED_suseconds_t -#endif - -#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) -typedef unsigned int wctype_t; -#define __DEFINED_wctype_t -#endif - - -#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) -typedef float float_t; -#define __DEFINED_float_t -#endif - -#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) -typedef double double_t; -#define __DEFINED_double_t -#endif - - -#ifndef __cplusplus -#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) -typedef struct { _Alignas(8) long long __ll; long double __ld; } max_align_t; -#define __DEFINED_max_align_t -#endif - -#elif defined(__GNUC__) -#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) -typedef struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t; -#define __DEFINED_max_align_t -#endif - -#else -#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) -typedef struct { alignas(8) long long __ll; long double __ld; } max_align_t; -#define __DEFINED_max_align_t -#endif - -#endif - -// For canvas transfer implementation in Emscripten, use an extra control field -// to pass a pointer to a string denoting the WebGL canvases to transfer. -#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) -typedef struct { union { int __i[10]; volatile int __vi[10]; unsigned long __s[10]; } __u; const char *_a_transferredcanvases; } pthread_attr_t; -#define __DEFINED_pthread_attr_t -#endif - - -// END EMSCRIPTEN-SPECIFIC DEFINITIONS -// -// Below here are the shared musl definitions. The emscripten-specific definitions above will take precedence -// due to the `__DEFINED_` macro system. -#define __LITTLE_ENDIAN 1234 -#define __BIG_ENDIAN 4321 -#define __USE_TIME_BITS64 1 - -#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) -typedef unsigned _Addr size_t; -#define __DEFINED_size_t -#endif - -#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) -typedef unsigned _Addr uintptr_t; -#define __DEFINED_uintptr_t -#endif - -#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) -typedef _Addr ptrdiff_t; -#define __DEFINED_ptrdiff_t -#endif - -#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) -typedef _Addr ssize_t; -#define __DEFINED_ssize_t -#endif - -#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) -typedef _Addr intptr_t; -#define __DEFINED_intptr_t -#endif - -#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t) -typedef _Addr regoff_t; -#define __DEFINED_regoff_t -#endif - -#if defined(__NEED_register_t) && !defined(__DEFINED_register_t) -typedef _Reg register_t; -#define __DEFINED_register_t -#endif - -#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) -typedef _Int64 time_t; -#define __DEFINED_time_t -#endif - -#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) -typedef _Int64 suseconds_t; -#define __DEFINED_suseconds_t -#endif - - -// XXX EMSCRIPTEN: This file has been modified from the upstream musl version -// to make use of clang pre-defined macros whereever possible, eliminating -// possible inconsistencies. - -#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) -typedef __INT8_TYPE__ int8_t; -#define __DEFINED_int8_t -#endif - -#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) -typedef __INT16_TYPE__ int16_t; -#define __DEFINED_int16_t -#endif - -#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) -typedef __INT32_TYPE__ int32_t; -#define __DEFINED_int32_t -#endif - -#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) -typedef __INT64_TYPE__ int64_t; -#define __DEFINED_int64_t -#endif - -#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) -typedef __INTMAX_TYPE__ intmax_t; -#define __DEFINED_intmax_t -#endif - -#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) -typedef __UINT8_TYPE__ uint8_t; -#define __DEFINED_uint8_t -#endif - -#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) -typedef __UINT16_TYPE__ uint16_t; -#define __DEFINED_uint16_t -#endif - -#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) -typedef __UINT32_TYPE__ uint32_t; -#define __DEFINED_uint32_t -#endif - -#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) -typedef __UINT64_TYPE__ uint64_t; -#define __DEFINED_uint64_t -#endif - -#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t) -typedef __UINT64_TYPE__ u_int64_t; -#define __DEFINED_u_int64_t -#endif - -#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) -typedef __UINTMAX_TYPE__ uintmax_t; -#define __DEFINED_uintmax_t -#endif - - -#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) -typedef unsigned mode_t; -#define __DEFINED_mode_t -#endif - -#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) -typedef unsigned _Reg nlink_t; -#define __DEFINED_nlink_t -#endif - -#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) -typedef _Int64 off_t; -#define __DEFINED_off_t -#endif - -#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) -typedef unsigned _Int64 ino_t; -#define __DEFINED_ino_t -#endif - -#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) -typedef unsigned _Int64 dev_t; -#define __DEFINED_dev_t -#endif - -#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) -typedef long blksize_t; -#define __DEFINED_blksize_t -#endif - -#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) -typedef _Int64 blkcnt_t; -#define __DEFINED_blkcnt_t -#endif - -#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) -typedef unsigned _Int64 fsblkcnt_t; -#define __DEFINED_fsblkcnt_t -#endif - -#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) -typedef unsigned _Int64 fsfilcnt_t; -#define __DEFINED_fsfilcnt_t -#endif - - -#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) -typedef unsigned wint_t; -#define __DEFINED_wint_t -#endif - -#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) -typedef unsigned long wctype_t; -#define __DEFINED_wctype_t -#endif - - -#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) -typedef void * timer_t; -#define __DEFINED_timer_t -#endif - -#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) -typedef int clockid_t; -#define __DEFINED_clockid_t -#endif - -#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) -typedef long clock_t; -#define __DEFINED_clock_t -#endif - -#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) -struct timeval { time_t tv_sec; suseconds_t tv_usec; }; -#define __DEFINED_struct_timeval -#endif - -#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) -struct timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); }; -#define __DEFINED_struct_timespec -#endif - - -#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) -typedef int pid_t; -#define __DEFINED_pid_t -#endif - -#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) -typedef unsigned id_t; -#define __DEFINED_id_t -#endif - -#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) -typedef unsigned uid_t; -#define __DEFINED_uid_t -#endif - -#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) -typedef unsigned gid_t; -#define __DEFINED_gid_t -#endif - -#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) -typedef int key_t; -#define __DEFINED_key_t -#endif - -#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) -typedef unsigned useconds_t; -#define __DEFINED_useconds_t -#endif - - -#ifdef __cplusplus -#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) -typedef unsigned long pthread_t; -#define __DEFINED_pthread_t -#endif - -#else -#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) -typedef struct __pthread * pthread_t; -#define __DEFINED_pthread_t -#endif - -#endif -#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) -typedef int pthread_once_t; -#define __DEFINED_pthread_once_t -#endif - -#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) -typedef unsigned pthread_key_t; -#define __DEFINED_pthread_key_t -#endif - -#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) -typedef int pthread_spinlock_t; -#define __DEFINED_pthread_spinlock_t -#endif - -#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) -typedef struct { unsigned __attr; } pthread_mutexattr_t; -#define __DEFINED_pthread_mutexattr_t -#endif - -#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) -typedef struct { unsigned __attr; } pthread_condattr_t; -#define __DEFINED_pthread_condattr_t -#endif - -#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) -typedef struct { unsigned __attr; } pthread_barrierattr_t; -#define __DEFINED_pthread_barrierattr_t -#endif - -#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) -typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; -#define __DEFINED_pthread_rwlockattr_t -#endif - - -#if defined(__NEED_struct__IO_FILE) && !defined(__DEFINED_struct__IO_FILE) -struct _IO_FILE { char __x; }; -#define __DEFINED_struct__IO_FILE -#endif - -#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) -typedef struct _IO_FILE FILE; -#define __DEFINED_FILE -#endif - - -#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) -typedef __builtin_va_list va_list; -#define __DEFINED_va_list -#endif - -#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list) -typedef __builtin_va_list __isoc_va_list; -#define __DEFINED___isoc_va_list -#endif - - -#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t) -typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; -#define __DEFINED_mbstate_t -#endif - - -#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) -typedef struct __locale_struct * locale_t; -#define __DEFINED_locale_t -#endif - - -// Musl uses 128 bytes for sigset_t, presumably for some kind of ABI -// compatability with the kernel or GLIBC, but in emscripten we can be precise. -// Since we have _NSIG = 65 which only need 2 `long`s for the bitmask. -// The signals we support are -// 1 - 31 - standard POSIX signals (see emscripten/bits/signal.h) -// 32 - 34 - pthread-specific signals (see pthread_impl.h> -// 35 - 65 - user-defined RT signals (we don't currently have any test coverage of these). -#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) -typedef struct __sigset_t { unsigned long __bits[2]; } sigset_t; -#define __DEFINED_sigset_t -#endif - - -#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) -struct iovec { void *iov_base; size_t iov_len; }; -#define __DEFINED_struct_iovec -#endif - - -#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize) -struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; }; -#define __DEFINED_struct_winsize -#endif - - -#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) -typedef unsigned socklen_t; -#define __DEFINED_socklen_t -#endif - -#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) -typedef unsigned short sa_family_t; -#define __DEFINED_sa_family_t -#endif - - -#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) -typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t; -#define __DEFINED_pthread_attr_t -#endif - -#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) -typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t; -#define __DEFINED_pthread_mutex_t -#endif - -#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t) -typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t; -#define __DEFINED_mtx_t -#endif - -#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) -typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } pthread_cond_t; -#define __DEFINED_pthread_cond_t -#endif - -#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t) -typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } cnd_t; -#define __DEFINED_cnd_t -#endif - -#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) -typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t; -#define __DEFINED_pthread_rwlock_t -#endif - -#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) -typedef struct { union { int __i[sizeof(long)==8?8:5]; volatile int __vi[sizeof(long)==8?8:5]; void *__p[sizeof(long)==8?4:5]; } __u; } pthread_barrier_t; -#define __DEFINED_pthread_barrier_t -#endif - - -#undef _Addr -#undef _Int64 -#undef _Reg diff --git a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in deleted file mode 100644 index 1f3168b2f8627..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The .h version of this file is generated from the .h.in. - * See update_alltypes.sh. - */ -#define _Addr __PTRDIFF_TYPE__ -#define _Int64 __INT64_TYPE__ -#define _Reg __PTRDIFF_TYPE__ - -#define __BYTE_ORDER 1234 -#define __LONG_MAX __LONG_MAX__ - -#ifndef __cplusplus -TYPEDEF __WCHAR_TYPE__ wchar_t; -#endif -TYPEDEF __WINT_TYPE__ wint_t; - -// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 -TYPEDEF int blkcnt_t; -TYPEDEF int blksize_t; -TYPEDEF int clock_t; -TYPEDEF unsigned int dev_t; -TYPEDEF int suseconds_t; -TYPEDEF unsigned int wctype_t; - -TYPEDEF float float_t; -TYPEDEF double double_t; - -#ifndef __cplusplus -TYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t; -#elif defined(__GNUC__) -TYPEDEF struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t; -#else -TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t; -#endif - -// For canvas transfer implementation in Emscripten, use an extra control field -// to pass a pointer to a string denoting the WebGL canvases to transfer. -TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; unsigned long __s[10]; } __u; const char *_a_transferredcanvases; } pthread_attr_t; - -// END EMSCRIPTEN-SPECIFIC DEFINITIONS -// -// Below here are the shared musl definitions. The emscripten-specific definitions above will take precedence -// due to the `__DEFINED_` macro system. diff --git a/system/lib/libc/musl/arch/emscripten/bits/endian.h b/system/lib/libc/musl/arch/emscripten/bits/endian.h deleted file mode 100644 index 172c338f5080a..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/endian.h +++ /dev/null @@ -1 +0,0 @@ -#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/system/lib/libc/musl/arch/emscripten/bits/errno.h b/system/lib/libc/musl/arch/emscripten/bits/errno.h deleted file mode 100644 index 43a8a6bac049b..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/errno.h +++ /dev/null @@ -1,144 +0,0 @@ -#include - -#define EPERM __WASI_ERRNO_PERM -#define ENOENT __WASI_ERRNO_NOENT -#define ESRCH __WASI_ERRNO_SRCH -#define EINTR __WASI_ERRNO_INTR -#define EIO __WASI_ERRNO_IO -#define ENXIO __WASI_ERRNO_NXIO -#define E2BIG __WASI_ERRNO_2BIG -#define ENOEXEC __WASI_ERRNO_NOEXEC -#define EBADF __WASI_ERRNO_BADF -#define ECHILD __WASI_ERRNO_CHILD -#define EAGAIN __WASI_ERRNO_AGAIN -#define ENOMEM __WASI_ERRNO_NOMEM -#define EACCES __WASI_ERRNO_ACCES -#define EFAULT __WASI_ERRNO_FAULT -#define EBUSY __WASI_ERRNO_BUSY -#define EEXIST __WASI_ERRNO_EXIST -#define EXDEV __WASI_ERRNO_XDEV -#define ENODEV __WASI_ERRNO_NODEV -#define ENOTDIR __WASI_ERRNO_NOTDIR -#define EISDIR __WASI_ERRNO_ISDIR -#define EINVAL __WASI_ERRNO_INVAL -#define ENFILE __WASI_ERRNO_NFILE -#define EMFILE __WASI_ERRNO_MFILE -#define ENOTTY __WASI_ERRNO_NOTTY -#define ETXTBSY __WASI_ERRNO_TXTBSY -#define EFBIG __WASI_ERRNO_FBIG -#define ENOSPC __WASI_ERRNO_NOSPC -#define ESPIPE __WASI_ERRNO_SPIPE -#define EROFS __WASI_ERRNO_ROFS -#define EMLINK __WASI_ERRNO_MLINK -#define EPIPE __WASI_ERRNO_PIPE -#define EDOM __WASI_ERRNO_DOM -#define ERANGE __WASI_ERRNO_RANGE -#define EDEADLK __WASI_ERRNO_DEADLK -#define ENAMETOOLONG __WASI_ERRNO_NAMETOOLONG -#define ENOLCK __WASI_ERRNO_NOLCK -#define ENOSYS __WASI_ERRNO_NOSYS -#define ENOTEMPTY __WASI_ERRNO_NOTEMPTY -#define ELOOP __WASI_ERRNO_LOOP -#define ENOMSG __WASI_ERRNO_NOMSG -#define EIDRM __WASI_ERRNO_IDRM -#define ENOLINK __WASI_ERRNO_NOLINK -#define EPROTO __WASI_ERRNO_PROTO -#define EMULTIHOP __WASI_ERRNO_MULTIHOP -#define EBADMSG __WASI_ERRNO_BADMSG -#define EOVERFLOW __WASI_ERRNO_OVERFLOW -#define EILSEQ __WASI_ERRNO_ILSEQ -#define ENOTSOCK __WASI_ERRNO_NOTSOCK -#define EDESTADDRREQ __WASI_ERRNO_DESTADDRREQ -#define EMSGSIZE __WASI_ERRNO_MSGSIZE -#define EPROTOTYPE __WASI_ERRNO_PROTOTYPE -#define ENOPROTOOPT __WASI_ERRNO_NOPROTOOPT -#define EPROTONOSUPPORT __WASI_ERRNO_PROTONOSUPPORT -#define EAFNOSUPPORT __WASI_ERRNO_AFNOSUPPORT -#define EADDRINUSE __WASI_ERRNO_ADDRINUSE -#define EADDRNOTAVAIL __WASI_ERRNO_ADDRNOTAVAIL -#define ENETDOWN __WASI_ERRNO_NETDOWN -#define ENETUNREACH __WASI_ERRNO_NETUNREACH -#define ENETRESET __WASI_ERRNO_NETRESET -#define ECONNABORTED __WASI_ERRNO_CONNABORTED -#define ECONNRESET __WASI_ERRNO_CONNRESET -#define ENOBUFS __WASI_ERRNO_NOBUFS -#define EISCONN __WASI_ERRNO_ISCONN -#define ENOTCONN __WASI_ERRNO_NOTCONN -#define ETIMEDOUT __WASI_ERRNO_TIMEDOUT -#define ECONNREFUSED __WASI_ERRNO_CONNREFUSED -#define EHOSTUNREACH __WASI_ERRNO_HOSTUNREACH -#define EALREADY __WASI_ERRNO_ALREADY -#define EINPROGRESS __WASI_ERRNO_INPROGRESS -#define ESTALE __WASI_ERRNO_STALE -#define EDQUOT __WASI_ERRNO_DQUOT -#define ECANCELED __WASI_ERRNO_CANCELED -#define EOWNERDEAD __WASI_ERRNO_OWNERDEAD -#define ENOTRECOVERABLE __WASI_ERRNO_NOTRECOVERABLE - -// Codes without a wasi equivalent, make sure they start -// above the wasi ones, which are dense [1,76]. -// Also try to fit the codes in a single byte signed wasm SLEB. - -#define ENOSTR 100 -#define EBFONT 101 -#define EBADSLT 102 -#define EBADRQC 103 -#define ENOANO 104 -#define ENOTBLK 105 -#define ECHRNG 106 -#define EL3HLT 107 -#define EL3RST 108 -#define ELNRNG 109 -#define EUNATCH 110 -#define ENOCSI 111 -#define EL2HLT 112 -#define EBADE 113 -#define EBADR 114 -#define EXFULL 115 -#define ENODATA 116 -#define ETIME 117 -#define ENOSR 118 -#define ENONET 119 -#define ENOPKG 120 -#define EREMOTE 121 -#define EADV 122 -#define ESRMNT 123 -#define ECOMM 124 -#define EDOTDOT 125 -#define ENOTUNIQ 126 -#define EBADFD 127 -#define EREMCHG 128 -#define ELIBACC 129 -#define ELIBBAD 130 -#define ELIBSCN 131 -#define ELIBMAX 132 -#define ELIBEXEC 133 -#define ERESTART 134 -#define ESTRPIPE 135 -#define EUSERS 136 -#define ESOCKTNOSUPPORT 137 -#define EOPNOTSUPP 138 -#define EPFNOSUPPORT 139 -#define ESHUTDOWN 140 -#define ETOOMANYREFS 141 -#define EHOSTDOWN 142 -#define EUCLEAN 143 -#define ENOTNAM 144 -#define ENAVAIL 145 -#define EISNAM 146 -#define EREMOTEIO 147 -#define ENOMEDIUM 148 -#define EMEDIUMTYPE 149 -#define ENOKEY 150 -#define EKEYEXPIRED 151 -#define EKEYREVOKED 152 -#define EKEYREJECTED 153 -#define ERFKILL 154 -#define EHWPOISON 155 -#define EL2NSYNC 156 - -// codes which musl defines as aliases - -#define EWOULDBLOCK EAGAIN -#define EDEADLOCK EDEADLK -#define ENOTSUP EOPNOTSUPP diff --git a/system/lib/libc/musl/arch/emscripten/bits/fenv.h b/system/lib/libc/musl/arch/emscripten/bits/fenv.h deleted file mode 100644 index d3512cb6f7f53..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/fenv.h +++ /dev/null @@ -1,27 +0,0 @@ -#define FE_ALL_EXCEPT 0 - -#define FE_TONEAREST 0 -#define FE_DOWNWARD 0x400 -#define FE_UPWARD 0x800 -#define FE_TOWARDZERO 0xc00 - -typedef unsigned short fexcept_t; - -typedef struct { - unsigned short __control_word; - unsigned short __unused1; - unsigned short __status_word; - unsigned short __unused2; - unsigned short __tags; - unsigned short __unused3; - unsigned int __eip; - unsigned short __cs_selector; - unsigned int __opcode:11; - unsigned int __unused4:5; - unsigned int __data_offset; - unsigned short __data_selector; - unsigned short __unused5; - unsigned int __mxcsr; -} fenv_t; - -#define FE_DFL_ENV ((const fenv_t *) -1) diff --git a/system/lib/libc/musl/arch/emscripten/bits/float.h b/system/lib/libc/musl/arch/emscripten/bits/float.h deleted file mode 100644 index 53ec2d10876e6..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/float.h +++ /dev/null @@ -1,17 +0,0 @@ -#define FLT_ROUNDS 1 -#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ - -#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ -#define LDBL_MIN __LDBL_MIN__ -#define LDBL_MAX __LDBL_MAX__ -#define LDBL_EPSILON __LDBL_EPSILON__ - -#define LDBL_MANT_DIG __LDBL_MANT_DIG__ -#define LDBL_MIN_EXP __LDBL_MIN_EXP__ -#define LDBL_MAX_EXP __LDBL_MAX_EXP__ - -#define LDBL_DIG __LDBL_DIG__ -#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ -#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ - -#define DECIMAL_DIG __DECIMAL_DIG__ diff --git a/system/lib/libc/musl/arch/emscripten/bits/limits.h b/system/lib/libc/musl/arch/emscripten/bits/limits.h deleted file mode 100644 index 7a09fdc1d175d..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/limits.h +++ /dev/null @@ -1 +0,0 @@ -#define PAGE_SIZE 65536 diff --git a/system/lib/libc/musl/arch/emscripten/bits/posix.h b/system/lib/libc/musl/arch/emscripten/bits/posix.h deleted file mode 100644 index 30a38714f36dd..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/system/lib/libc/musl/arch/emscripten/bits/reg.h b/system/lib/libc/musl/arch/emscripten/bits/reg.h deleted file mode 100644 index 1c4987c775f11..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/reg.h +++ /dev/null @@ -1,6 +0,0 @@ -#undef __WORDSIZE -#ifdef __wasm64__ -#define __WORDSIZE 64 -#else -#define __WORDSIZE 32 -#endif diff --git a/system/lib/libc/musl/arch/emscripten/bits/setjmp.h b/system/lib/libc/musl/arch/emscripten/bits/setjmp.h deleted file mode 100644 index decd26dca07a0..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/setjmp.h +++ /dev/null @@ -1 +0,0 @@ -typedef unsigned long __jmp_buf[6]; diff --git a/system/lib/libc/musl/arch/emscripten/bits/signal.h b/system/lib/libc/musl/arch/emscripten/bits/signal.h deleted file mode 100644 index 58bc5e2c3a780..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/signal.h +++ /dev/null @@ -1,123 +0,0 @@ -#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - -#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 -#endif - -#ifdef _GNU_SOURCE -#define REG_GS 0 -#define REG_FS 1 -#define REG_ES 2 -#define REG_DS 3 -#define REG_EDI 4 -#define REG_ESI 5 -#define REG_EBP 6 -#define REG_ESP 7 -#define REG_EBX 8 -#define REG_EDX 9 -#define REG_ECX 10 -#define REG_EAX 11 -#define REG_TRAPNO 12 -#define REG_ERR 13 -#define REG_EIP 14 -#define REG_CS 15 -#define REG_EFL 16 -#define REG_UESP 17 -#define REG_SS 18 -#endif - -struct sigaltstack { - void *ss_sp; - int ss_flags; - size_t ss_size; -}; - -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -typedef int greg_t, gregset_t[19]; -typedef struct _fpstate { - unsigned long cw, sw, tag, ipoff, cssel, dataoff, datasel; - struct { - unsigned short significand[4], exponent; - } _st[8]; - unsigned long status; -} *fpregset_t; -struct sigcontext { - unsigned short gs, __gsh, fs, __fsh, es, __esh, ds, __dsh; - unsigned long edi, esi, ebp, esp, ebx, edx, ecx, eax; - unsigned long trapno, err, eip; - unsigned short cs, __csh; - unsigned long eflags, esp_at_signal; - unsigned short ss, __ssh; - struct _fpstate *fpstate; - unsigned long oldmask, cr2; -}; -typedef struct { - gregset_t gregs; - fpregset_t fpregs; - unsigned long oldmask, cr2; -} mcontext_t; -#else -typedef struct { - unsigned __space[22]; -} mcontext_t; -#endif - -typedef struct __ucontext { - unsigned long uc_flags; - struct __ucontext *uc_link; - stack_t uc_stack; - mcontext_t uc_mcontext; - sigset_t uc_sigmask; - unsigned long __fpregs_mem[28]; -} ucontext_t; - -#define SA_NOCLDSTOP 1 -#define SA_NOCLDWAIT 2 -#define SA_SIGINFO 4 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 -#define SA_RESTORER 0x04000000 - -#endif - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT SIGABRT -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL 29 -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED SIGSYS - -#define _NSIG 65 - diff --git a/system/lib/libc/musl/arch/emscripten/bits/stat.h b/system/lib/libc/musl/arch/emscripten/bits/stat.h deleted file mode 100644 index bfa9a597bcf6d..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/stat.h +++ /dev/null @@ -1,26 +0,0 @@ -/* copied from kernel definition, but with padding replaced - * by the corresponding correctly-sized userspace types. */ - -struct stat -{ - dev_t st_dev; -#ifndef __EMSCRIPTEN__ - int __st_dev_padding; - long __st_ino_truncated; -#endif - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; -#ifndef __EMSCRIPTEN__ - int __st_rdev_padding; -#endif - off_t st_size; - blksize_t st_blksize; - blkcnt_t st_blocks; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - ino_t st_ino; -}; diff --git a/system/lib/libc/musl/arch/emscripten/bits/syscall.h b/system/lib/libc/musl/arch/emscripten/bits/syscall.h deleted file mode 100644 index e3465a65c7406..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/syscall.h +++ /dev/null @@ -1,89 +0,0 @@ -#define SYS_chdir __syscall_chdir -#define SYS_chmod __syscall_chmod -#define SYS_getpid __syscall_getpid -#define SYS_pause __syscall_pause -#define SYS_sync __syscall_sync -#define SYS_rmdir __syscall_rmdir -#define SYS_dup __syscall_dup -#define SYS_acct __syscall_acct -#define SYS_ioctl __syscall_ioctl -#define SYS_setpgid __syscall_setpgid -#define SYS_umask __syscall_umask -#define SYS_getppid __syscall_getppid -#define SYS_setsid __syscall_setsid -#define SYS_getrusage __syscall_getrusage -#define SYS_munmap __syscall_munmap -#define SYS_fchmod __syscall_fchmod -#define SYS_getpriority __syscall_getpriority -#define SYS_setpriority __syscall_setpriority -#define SYS_wait4 __syscall_wait4 -#define SYS_setdomainname __syscall_setdomainname -#define SYS_uname __syscall_uname -#define SYS_mprotect __syscall_mprotect -#define SYS_getpgid __syscall_getpgid -#define SYS_fchdir __syscall_fchdir -#define SYS_msync __syscall_msync -#define SYS_getsid __syscall_getsid -#define SYS_fdatasync __syscall_fdatasync -#define SYS_mlock __syscall_mlock -#define SYS_munlock __syscall_munlock -#define SYS_mlockall __syscall_mlockall -#define SYS_munlockall __syscall_munlockall -#define SYS_mremap __syscall_mremap -#define SYS_poll __syscall_poll -#define SYS_getcwd __syscall_getcwd -#define SYS_mmap2 __syscall_mmap2 -#define SYS_truncate64 __syscall_truncate64 -#define SYS_ftruncate64 __syscall_ftruncate64 -#define SYS_stat64 __syscall_stat64 -#define SYS_lstat64 __syscall_lstat64 -#define SYS_fstat64 __syscall_fstat64 -#define SYS_getuid32 __syscall_getuid32 -#define SYS_getgid32 __syscall_getgid32 -#define SYS_geteuid32 __syscall_geteuid32 -#define SYS_getegid32 __syscall_getegid32 -#define SYS_getgroups32 __syscall_getgroups32 -#define SYS_fchown32 __syscall_fchown32 -#define SYS_getresuid32 __syscall_getresuid32 -#define SYS_getresgid32 __syscall_getresgid32 -#define SYS_mincore __syscall_mincore -#define SYS_madvise __syscall_madvise -#define SYS_getdents64 __syscall_getdents64 -#define SYS_fcntl64 __syscall_fcntl64 -#define SYS_statfs64 __syscall_statfs64 -#define SYS_fstatfs64 __syscall_fstatfs64 -#define SYS_fadvise64 __syscall_fadvise64 -#define SYS_openat __syscall_openat -#define SYS_mkdirat __syscall_mkdirat -#define SYS_mknodat __syscall_mknodat -#define SYS_fchownat __syscall_fchownat -#define SYS_newfstatat __syscall_newfstatat -#define SYS_unlinkat __syscall_unlinkat -#define SYS_renameat __syscall_renameat -#define SYS_linkat __syscall_linkat -#define SYS_symlinkat __syscall_symlinkat -#define SYS_readlinkat __syscall_readlinkat -#define SYS_fchmodat2 __syscall_fchmodat2 -#define SYS_faccessat __syscall_faccessat -#define SYS_utimensat __syscall_utimensat -#define SYS_fallocate __syscall_fallocate -#define SYS_dup3 __syscall_dup3 -#define SYS_pipe2 __syscall_pipe2 -#define SYS_recvmmsg __syscall_recvmmsg -#define SYS_prlimit64 __syscall_prlimit64 -#define SYS_sendmmsg __syscall_sendmmsg -#define SYS_socket __syscall_socket -#define SYS_socketpair __syscall_socketpair -#define SYS_bind __syscall_bind -#define SYS_connect __syscall_connect -#define SYS_listen __syscall_listen -#define SYS_accept4 __syscall_accept4 -#define SYS_getsockopt __syscall_getsockopt -#define SYS_setsockopt __syscall_setsockopt -#define SYS_getsockname __syscall_getsockname -#define SYS_getpeername __syscall_getpeername -#define SYS_sendto __syscall_sendto -#define SYS_sendmsg __syscall_sendmsg -#define SYS_recvfrom __syscall_recvfrom -#define SYS_recvmsg __syscall_recvmsg -#define SYS_shutdown __syscall_shutdown diff --git a/system/lib/libc/musl/arch/emscripten/bits/user.h b/system/lib/libc/musl/arch/emscripten/bits/user.h deleted file mode 100644 index fa623621eeba3..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/user.h +++ /dev/null @@ -1,48 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 - -typedef struct user_fpregs_struct -{ - long cwd, swd, twd, fip, fcs, foo, fos, st_space[20]; -} elf_fpregset_t; - -typedef struct user_fpxregs_struct -{ - unsigned short cwd, swd, twd, fop; - long fip, fcs, foo, fos, mxcsr, reserved; - long st_space[32], xmm_space[32], padding[56]; -} elf_fpxregset_t; - -struct user_regs_struct -{ - long ebx, ecx, edx, esi, edi, ebp, eax, xds, xes, xfs, xgs; - long orig_eax, eip, xcs, eflags, esp, xss; -}; - -#define ELF_NGREG 17 -typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG]; - -struct user -{ - struct user_regs_struct regs; - int u_fpvalid; - struct user_fpregs_struct i387; - unsigned long u_tsize; - unsigned long u_dsize; - unsigned long u_ssize; - unsigned long start_code; - unsigned long start_stack; - long signal; - int reserved; - struct user_regs_struct *u_ar0; - struct user_fpregs_struct *u_fpstate; - unsigned long magic; - char u_comm[32]; - int u_debugreg[8]; -}; - -#define PAGE_MASK (~(PAGE_SIZE-1)) -#define NBPG PAGE_SIZE -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) diff --git a/system/lib/libc/musl/arch/emscripten/crt_arch.h b/system/lib/libc/musl/arch/emscripten/crt_arch.h deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/system/lib/libc/musl/arch/emscripten/kstat.h b/system/lib/libc/musl/arch/emscripten/kstat.h deleted file mode 100644 index 72c5d0af803e6..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/kstat.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -#define kstat stat diff --git a/system/lib/libc/musl/arch/emscripten/pthread_arch.h b/system/lib/libc/musl/arch/emscripten/pthread_arch.h deleted file mode 100644 index a62934a5d2214..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/pthread_arch.h +++ /dev/null @@ -1,5 +0,0 @@ -uintptr_t __get_tp(void); - -#define TP_ADJ(p) (p) - -#define CANCEL_REG_IP 16 diff --git a/system/lib/libc/musl/arch/emscripten/syscall_arch.h b/system/lib/libc/musl/arch/emscripten/syscall_arch.h deleted file mode 100644 index cf9ad1048dc64..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/syscall_arch.h +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include - -// Compile as if we can pass uint64 values directly to the host. Binaryen will -// take care of splitting any i64 params into a pair of i32 values if needed. -#define __SYSCALL_LL_E(x) (x) -#define __SYSCALL_LL_O(x) (x) diff --git a/system/lib/libc/musl/arch/generic/bits/stdarg.h b/system/lib/libc/musl/arch/generic/bits/stdarg.h deleted file mode 100644 index fde378146d5df..0000000000000 --- a/system/lib/libc/musl/arch/generic/bits/stdarg.h +++ /dev/null @@ -1,4 +0,0 @@ -#define va_start(v,l) __builtin_va_start(v,l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v,l) __builtin_va_arg(v,l) -#define va_copy(d,s) __builtin_va_copy(d,s) diff --git a/system/lib/libc/musl/config.mak b/system/lib/libc/musl/config.mak deleted file mode 100644 index 5b46fcdcdedec..0000000000000 --- a/system/lib/libc/musl/config.mak +++ /dev/null @@ -1,32 +0,0 @@ -# This version of config.mak was generated by: -# ./configure -# Any changes made here will be lost if configure is re-run -AR = $(CROSS_COMPILE)ar -RANLIB = $(CROSS_COMPILE)ranlib -ARCH = x86_64 -SUBARCH = -ASMSUBARCH = -srcdir = . -prefix = /usr/local/musl -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin -libdir = $(prefix)/lib -includedir = $(prefix)/include -syslibdir = /lib -CC = gcc -CFLAGS = -CFLAGS_AUTO = -Os -pipe -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith -CFLAGS_C99FSE = -std=c99 -nostdinc -ffreestanding -fexcess-precision=standard -frounding-math -Wa,--noexecstack -CFLAGS_MEMOPS = -fno-tree-loop-distribute-patterns -CFLAGS_NOSSP = -fno-stack-protector -CPPFLAGS = -LDFLAGS = -LDFLAGS_AUTO = -Wl,--sort-section,alignment -Wl,--sort-common -Wl,--gc-sections -Wl,--hash-style=both -Wl,--no-undefined -Wl,--exclude-libs=ALL -Wl,--dynamic-list=./dynamic.list -CROSS_COMPILE = -LIBCC = -lgcc -lgcc_eh -OPTIMIZE_GLOBS = internal/*.c malloc/*.c string/*.c -ALL_TOOLS = obj/musl-gcc -TOOL_LIBS = lib/musl-gcc.specs -ADD_CFI = no -WRAPCC_GCC = $(CC) -AOBJS = $(LOBJS) diff --git a/system/lib/libc/musl/configure b/system/lib/libc/musl/configure index 13bda76840a31..bc9fbe48cc443 100755 --- a/system/lib/libc/musl/configure +++ b/system/lib/libc/musl/configure @@ -405,7 +405,7 @@ tryflag CFLAGS_NOSSP -fno-stack-protector # option is sufficient, and if not, add a macro to cripple these # functions with volatile... # -# XXX EMSCRIPTEN tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns +tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns # # Enable debugging if requessted. @@ -546,7 +546,7 @@ tryflag CFLAGS_AUTO -Wno-pointer-to-int-cast # tryflag CFLAGS_AUTO -Werror=implicit-function-declaration tryflag CFLAGS_AUTO -Werror=implicit-int -# XXX EMSCRIPTEN tryflag CFLAGS_AUTO -Werror=pointer-sign +tryflag CFLAGS_AUTO -Werror=pointer-sign tryflag CFLAGS_AUTO -Werror=pointer-arith tryflag CFLAGS_AUTO -Werror=int-conversion tryflag CFLAGS_AUTO -Werror=incompatible-pointer-types diff --git a/system/lib/libc/musl/include/alltypes.h.in b/system/lib/libc/musl/include/alltypes.h.in index 2da1da767eb97..d47aeea9aa8b8 100644 --- a/system/lib/libc/musl/include/alltypes.h.in +++ b/system/lib/libc/musl/include/alltypes.h.in @@ -12,21 +12,17 @@ TYPEDEF _Reg register_t; TYPEDEF _Int64 time_t; TYPEDEF _Int64 suseconds_t; -// XXX EMSCRIPTEN: This file has been modified from the upstream musl version -// to make use of clang pre-defined macros whereever possible, eliminating -// possible inconsistencies. - -TYPEDEF __INT8_TYPE__ int8_t; -TYPEDEF __INT16_TYPE__ int16_t; -TYPEDEF __INT32_TYPE__ int32_t; -TYPEDEF __INT64_TYPE__ int64_t; -TYPEDEF __INTMAX_TYPE__ intmax_t; -TYPEDEF __UINT8_TYPE__ uint8_t; -TYPEDEF __UINT16_TYPE__ uint16_t; -TYPEDEF __UINT32_TYPE__ uint32_t; -TYPEDEF __UINT64_TYPE__ uint64_t; -TYPEDEF __UINT64_TYPE__ u_int64_t; -TYPEDEF __UINTMAX_TYPE__ uintmax_t; +TYPEDEF signed char int8_t; +TYPEDEF signed short int16_t; +TYPEDEF signed int int32_t; +TYPEDEF signed _Int64 int64_t; +TYPEDEF signed _Int64 intmax_t; +TYPEDEF unsigned char uint8_t; +TYPEDEF unsigned short uint16_t; +TYPEDEF unsigned int uint32_t; +TYPEDEF unsigned _Int64 uint64_t; +TYPEDEF unsigned _Int64 u_int64_t; +TYPEDEF unsigned _Int64 uintmax_t; TYPEDEF unsigned mode_t; TYPEDEF unsigned _Reg nlink_t; @@ -77,14 +73,7 @@ TYPEDEF struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; TYPEDEF struct __locale_struct * locale_t; -// Musl uses 128 bytes for sigset_t, presumably for some kind of ABI -// compatability with the kernel or GLIBC, but in emscripten we can be precise. -// Since we have _NSIG = 65 which only need 2 `long`s for the bitmask. -// The signals we support are -// 1 - 31 - standard POSIX signals (see emscripten/bits/signal.h) -// 32 - 34 - pthread-specific signals (see pthread_impl.h> -// 35 - 65 - user-defined RT signals (we don't currently have any test coverage of these). -TYPEDEF struct __sigset_t { unsigned long __bits[2]; } sigset_t; +TYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t; STRUCT iovec { void *iov_base; size_t iov_len; }; diff --git a/system/lib/libc/musl/include/fcntl.h b/system/lib/libc/musl/include/fcntl.h index cce43031f112d..53f98a8bed98a 100644 --- a/system/lib/libc/musl/include/fcntl.h +++ b/system/lib/libc/musl/include/fcntl.h @@ -1,10 +1,6 @@ #ifndef _FCNTL_H #define _FCNTL_H -#ifdef __EMSCRIPTEN__ -#include -#endif - #ifdef __cplusplus extern "C" { #endif @@ -79,15 +75,9 @@ int posix_fallocate(int, off_t, off_t); #undef SEEK_SET #undef SEEK_CUR #undef SEEK_END -#ifdef __EMSCRIPTEN__ -#define SEEK_SET __WASI_WHENCE_SET -#define SEEK_CUR __WASI_WHENCE_CUR -#define SEEK_END __WASI_WHENCE_END -#else #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 -#endif // EMSCRIPTEN #ifndef S_IRUSR #define S_ISUID 04000 diff --git a/system/lib/libc/musl/include/features.h b/system/lib/libc/musl/include/features.h index 952ffd968592b..85cfb72a0d427 100644 --- a/system/lib/libc/musl/include/features.h +++ b/system/lib/libc/musl/include/features.h @@ -16,13 +16,6 @@ #define _XOPEN_SOURCE 700 #endif -#if defined(__EMSCRIPTEN__) && defined(_GNU_SOURCE) -// In emscripten the LFS functions are kept around when _GNU_SOURCE is -// defined, for increased compatabiliy. This is also what glibc does. -#undef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE 1 -#endif - #if __STDC_VERSION__ >= 199901L #define __restrict restrict #elif !defined(__GNUC__) diff --git a/system/lib/libc/musl/include/inttypes.h b/system/lib/libc/musl/include/inttypes.h index 90c35c8664ae8..61dcb72731f0d 100644 --- a/system/lib/libc/musl/include/inttypes.h +++ b/system/lib/libc/musl/include/inttypes.h @@ -22,12 +22,7 @@ uintmax_t strtoumax(const char *__restrict, char **__restrict, int); intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int); uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); -#if defined(__EMSCRIPTEN__) -// Under emscripten __PTRDIFF_TYPE__ and therefor intptr_t are defined to -// be `long int` even on wasm32. -#define __PRI64 "ll" -#define __PRIPTR "l" -#elif UINTPTR_MAX == UINT64_MAX +#if UINTPTR_MAX == UINT64_MAX #define __PRI64 "l" #define __PRIPTR "l" #else diff --git a/system/lib/libc/musl/include/limits.h b/system/lib/libc/musl/include/limits.h index a1365cfc15e22..53a27b9de43fa 100644 --- a/system/lib/libc/musl/include/limits.h +++ b/system/lib/libc/musl/include/limits.h @@ -51,14 +51,7 @@ #define SYMLOOP_MAX 40 #define WORD_BIT 32 #define SSIZE_MAX LONG_MAX -#ifdef __EMSCRIPTEN__ -// We depend on the JS API to reteive the local name for the current -// timezone and this can sometimes exceed 6 chars. For example: -// TZ='Asia/Kathmandu' yields 'GMT+5:45'. -#define TZNAME_MAX 16 -#else #define TZNAME_MAX 6 -#endif #define TTY_NAME_MAX 32 #define HOST_NAME_MAX 255 diff --git a/system/lib/libc/musl/include/locale.h b/system/lib/libc/musl/include/locale.h index 624547f6c3e39..11106fea878a6 100644 --- a/system/lib/libc/musl/include/locale.h +++ b/system/lib/libc/musl/include/locale.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/setjmp.h b/system/lib/libc/musl/include/setjmp.h index af72c80cdbce0..1976af231b8c4 100644 --- a/system/lib/libc/musl/include/setjmp.h +++ b/system/lib/libc/musl/include/setjmp.h @@ -25,15 +25,9 @@ typedef struct __jmp_buf_tag { || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) typedef jmp_buf sigjmp_buf; -/* XXX EMSCRIPTEN: No signals support, alias sigsetjmp and siglongjmp to their non-signals counterparts. */ -#if __EMSCRIPTEN__ && !defined(LLVM_LIBC) -#define sigsetjmp(buf, x) setjmp((buf)) -#define siglongjmp(buf, val) longjmp(buf, val) -#else int sigsetjmp (sigjmp_buf, int) __setjmp_attr; _Noreturn void siglongjmp (sigjmp_buf, int); #endif -#endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) diff --git a/system/lib/libc/musl/include/signal.h b/system/lib/libc/musl/include/signal.h index e75cb860a3f6d..c347f8610a3f2 100644 --- a/system/lib/libc/musl/include/signal.h +++ b/system/lib/libc/musl/include/signal.h @@ -282,7 +282,7 @@ int sigandset(sigset_t *, const sigset_t *, const sigset_t *); #define SIG_ERR ((void (*)(int))-1) #define SIG_DFL ((void (*)(int)) 0) -#define SIG_IGN ((void (*)(int))-2) /* XXX EMSCRIPTEN: use -2 since 1 is a valid function address */ +#define SIG_IGN ((void (*)(int)) 1) typedef int sig_atomic_t; diff --git a/system/lib/libc/musl/include/stddef.h b/system/lib/libc/musl/include/stddef.h index 5fa18390a80b0..f25b86396e80a 100644 --- a/system/lib/libc/musl/include/stddef.h +++ b/system/lib/libc/musl/include/stddef.h @@ -1,7 +1,7 @@ #ifndef _STDDEF_H #define _STDDEF_H -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/stdint.h b/system/lib/libc/musl/include/stdint.h index 8239d4703523a..a2968197dbe23 100644 --- a/system/lib/libc/musl/include/stdint.h +++ b/system/lib/libc/musl/include/stdint.h @@ -19,104 +19,99 @@ #include -// XXX EMSCRIPTEN: This file has been modified from the upstream musl version -// to make use of clang pre-defined macros whereever possible, eliminating -// possible inconsistencies. - -typedef __INT_FAST8_TYPE__ int_fast8_t; -typedef __INT_FAST16_TYPE__ int_fast16_t; -typedef __INT_FAST32_TYPE__ int_fast32_t; -typedef __INT_FAST64_TYPE__ int_fast64_t; - -typedef __INT_LEAST8_TYPE__ int_least8_t; -typedef __INT_LEAST16_TYPE__ int_least16_t; -typedef __INT_LEAST32_TYPE__ int_least32_t; -typedef __INT_LEAST64_TYPE__ int_least64_t; - -typedef __UINT_FAST8_TYPE__ uint_fast8_t; -typedef __UINT_FAST16_TYPE__ uint_fast16_t; -typedef __UINT_FAST32_TYPE__ uint_fast32_t; -typedef __UINT_FAST64_TYPE__ uint_fast64_t; - -typedef __UINT_LEAST8_TYPE__ uint_least8_t; -typedef __UINT_LEAST16_TYPE__ uint_least16_t; -typedef __UINT_LEAST32_TYPE__ uint_least32_t; -typedef __UINT_LEAST64_TYPE__ uint_least64_t; - -#define INT8_MIN (-1-__INT8_MAX__) -#define INT16_MIN (-1-__INT16_MAX__) -#define INT32_MIN (-1-__INT32_MAX__) -#define INT64_MIN (-1-__INT64_MAX__) - -#define INT8_MAX __INT8_MAX__ -#define INT16_MAX __INT16_MAX__ -#define INT32_MAX __INT32_MAX__ -#define INT64_MAX __INT64_MAX__ - -#define UINT8_MAX __UINT8_MAX__ -#define UINT16_MAX __UINT16_MAX__ -#define UINT32_MAX __UINT32_MAX__ -#define UINT64_MAX __UINT64_MAX__ - -#define INT_FAST8_MIN (-1-__INT_FAST8_MAX__) -#define INT_FAST16_MIN (-1-__INT_FAST16_MAX__) -#define INT_FAST32_MIN (-1-__INT_FAST32_MAX__) -#define INT_FAST64_MIN (-1-__INT_FAST64_MAX__) - -#define INT_LEAST8_MIN (-1-__INT_LEAST8_MAX__) -#define INT_LEAST16_MIN (-1-__INT_LEAST16_MAX__) -#define INT_LEAST32_MIN (-1-__INT_LEAST32_MAX__) -#define INT_LEAST64_MIN (-1-__INT_LEAST64_MAX__) - -#define INT_FAST8_MAX __INT_FAST8_MAX__ -#define INT_FAST16_MAX __INT_FAST16_MAX__ -#define INT_FAST32_MAX __INT_FAST32_MAX__ -#define INT_FAST64_MAX __INT_FAST64_MAX__ - -#define INT_LEAST8_MAX __INT_LEAST8_MAX__ -#define INT_LEAST16_MAX __INT_LEAST16_MAX__ -#define INT_LEAST32_MAX __INT_LEAST32_MAX__ -#define INT_LEAST64_MAX __INT_LEAST64_MAX__ - -#define UINT_FAST8_MAX __UINT_FAST8_MAX__ -#define UINT_FAST16_MAX __UINT_FAST16_MAX__ -#define UINT_FAST32_MAX __UINT_FAST32_MAX__ -#define UINT_FAST64_MAX __UINT_FAST64_MAX__ - -#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ -#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ -#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ -#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ - -#define INTMAX_MIN (-1-__INTMAX_MAX__) -#define INTMAX_MAX __INTMAX_MAX__ -#define UINTMAX_MAX __UINTMAX_MAX__ - -#define WCHAR_MAX __WCHAR_MAX__ -#define WINT_MAX __WINT_MAX__ -#define INTPTR_MAX __INTPTR_MAX__ -#define UINTPTR_MAX __UINTPTR_MAX__ -#define PTRDIFF_MAX __PTRDIFF_MAX__ -#define SIZE_MAX __SIZE_MAX__ - -#define WINT_MIN (-1-__WINT_MAX__) -#define WCHAR_MIN (-1-__WCHAR_MAX__) -#define INTPTR_MIN (-1-__INTPTR_MAX__) -#define PTRDIFF_MIN (-1-__PTRDIFF_MAX__) +typedef int8_t int_fast8_t; +typedef int64_t int_fast64_t; + +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; + +typedef uint8_t uint_fast8_t; +typedef uint64_t uint_fast64_t; + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +#define INT8_MIN (-1-0x7f) +#define INT16_MIN (-1-0x7fff) +#define INT32_MIN (-1-0x7fffffff) +#define INT64_MIN (-1-0x7fffffffffffffff) + +#define INT8_MAX (0x7f) +#define INT16_MAX (0x7fff) +#define INT32_MAX (0x7fffffff) +#define INT64_MAX (0x7fffffffffffffff) + +#define UINT8_MAX (0xff) +#define UINT16_MAX (0xffff) +#define UINT32_MAX (0xffffffffu) +#define UINT64_MAX (0xffffffffffffffffu) + +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST64_MAX INT64_MAX + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST64_MAX UINT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +#define WINT_MIN 0U +#define WINT_MAX UINT32_MAX + +#if L'\0'-1 > 0 +#define WCHAR_MAX (0xffffffffu+L'\0') +#define WCHAR_MIN (0+L'\0') +#else +#define WCHAR_MAX (0x7fffffff+L'\0') +#define WCHAR_MIN (-1-0x7fffffff+L'\0') +#endif #define SIG_ATOMIC_MIN INT32_MIN #define SIG_ATOMIC_MAX INT32_MAX -#define INT8_C __INT8_C -#define INT16_C __INT16_C -#define INT32_C __INT32_C -#define INT64_C __INT64_C -#define INTMAX_C __INTMAX_C - -#define UINT8_C __UINT8_C -#define UINT16_C __UINT16_C -#define UINT32_C __UINT32_C -#define UINT64_C __UINT64_C -#define UINTMAX_C __UINTMAX_C +#include + +#define INT8_C(c) c +#define INT16_C(c) c +#define INT32_C(c) c + +#define UINT8_C(c) c +#define UINT16_C(c) c +#define UINT32_C(c) c ## U + +#if UINTPTR_MAX == UINT64_MAX +#define INT64_C(c) c ## L +#define UINT64_C(c) c ## UL +#define INTMAX_C(c) c ## L +#define UINTMAX_C(c) c ## UL +#else +#define INT64_C(c) c ## LL +#define UINT64_C(c) c ## ULL +#define INTMAX_C(c) c ## LL +#define UINTMAX_C(c) c ## ULL +#endif #endif diff --git a/system/lib/libc/musl/include/stdio.h b/system/lib/libc/musl/include/stdio.h index 609fad5fdff3e..cb858618512d8 100644 --- a/system/lib/libc/musl/include/stdio.h +++ b/system/lib/libc/musl/include/stdio.h @@ -1,10 +1,6 @@ #ifndef _STDIO_H #define _STDIO_H -#ifdef __EMSCRIPTEN__ -#include -#endif - #ifdef __cplusplus extern "C" { #endif @@ -29,7 +25,7 @@ extern "C" { #include -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L @@ -43,15 +39,9 @@ extern "C" { #undef SEEK_SET #undef SEEK_CUR #undef SEEK_END -#ifdef __EMSCRIPTEN__ -#define SEEK_SET __WASI_WHENCE_SET -#define SEEK_CUR __WASI_WHENCE_CUR -#define SEEK_END __WASI_WHENCE_END -#else #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 -#endif // EMSCRIPTEN #define _IOFBF 0 #define _IOLBF 1 diff --git a/system/lib/libc/musl/include/stdlib.h b/system/lib/libc/musl/include/stdlib.h index efbd0b55a99e2..475190bfa2c9f 100644 --- a/system/lib/libc/musl/include/stdlib.h +++ b/system/lib/libc/musl/include/stdlib.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/string.h b/system/lib/libc/musl/include/string.h index 874680c563b2c..83e2b946486f6 100644 --- a/system/lib/libc/musl/include/string.h +++ b/system/lib/libc/musl/include/string.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/time.h b/system/lib/libc/musl/include/time.h index a91e1f76b4a44..3d94837205ad5 100644 --- a/system/lib/libc/musl/include/time.h +++ b/system/lib/libc/musl/include/time.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/unistd.h b/system/lib/libc/musl/include/unistd.h index d98a7460db4d3..5bc7f7982f5ed 100644 --- a/system/lib/libc/musl/include/unistd.h +++ b/system/lib/libc/musl/include/unistd.h @@ -1,10 +1,6 @@ #ifndef _UNISTD_H #define _UNISTD_H -#ifdef __EMSCRIPTEN__ -#include -#endif - #ifdef __cplusplus extern "C" { #endif @@ -15,19 +11,13 @@ extern "C" { #define STDOUT_FILENO 1 #define STDERR_FILENO 2 -#ifdef __EMSCRIPTEN__ -#define SEEK_SET __WASI_WHENCE_SET -#define SEEK_CUR __WASI_WHENCE_CUR -#define SEEK_END __WASI_WHENCE_END -#else #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_DATA 3 #define SEEK_HOLE 4 -#endif // EMSCRIPTEN -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L @@ -187,7 +177,7 @@ void setusershell(void); void endusershell(void); char *getusershell(void); int acct(const char *); -/* XXX EMSCRIPTEN long syscall(long, ...); */ +long syscall(long, ...); int execvpe(const char *, char *const [], char *const []); int issetugid(void); int getentropy(void *, size_t); @@ -239,44 +229,20 @@ pid_t gettid(void); #define _POSIX_FSYNC _POSIX_VERSION #define _POSIX_NO_TRUNC 1 #define _POSIX_RAW_SOCKETS _POSIX_VERSION - -#ifndef __EMSCRIPTEN__ #define _POSIX_REALTIME_SIGNALS _POSIX_VERSION -#else -#define _POSIX_REALTIME_SIGNALS -1 -#endif - #define _POSIX_REGEXP 1 #define _POSIX_SAVED_IDS 1 #define _POSIX_SHELL 1 - -#ifndef __EMSCRIPTEN__ #define _POSIX_SPAWN _POSIX_VERSION -#else -#define _POSIX_SPAWN -1 -#endif - #define _POSIX_VDISABLE 0 -#if defined(__EMSCRIPTEN__) && !defined(_REENTRANT) /* XXX Emscripten doesn't always support pthreads */ -#define _POSIX_THREADS -1 -#else #define _POSIX_THREADS _POSIX_VERSION -#endif -#ifndef __EMSCRIPTEN__ #define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION -#else -#define _POSIX_THREAD_PROCESS_SHARED -1 -#endif #define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION #define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION #define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION #define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION -#ifdef __EMSCRIPTEN__ -#define _POSIX_THREAD_CPUTIME -1 -#else #define _POSIX_THREAD_CPUTIME _POSIX_VERSION -#endif #define _POSIX_TIMERS _POSIX_VERSION #define _POSIX_TIMEOUTS _POSIX_VERSION #define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION @@ -287,9 +253,7 @@ pid_t gettid(void); #define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION #define _POSIX_ASYNCHRONOUS_IO _POSIX_VERSION #define _POSIX_SEMAPHORES _POSIX_VERSION -#ifndef __EMSCRIPTEN__ #define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION -#endif #define _POSIX2_C_BIND _POSIX_VERSION diff --git a/system/lib/libc/musl/include/wchar.h b/system/lib/libc/musl/include/wchar.h index 18eee67ca6c66..ed5d774dfa968 100644 --- a/system/lib/libc/musl/include/wchar.h +++ b/system/lib/libc/musl/include/wchar.h @@ -38,7 +38,7 @@ extern "C" { #define WCHAR_MIN (-1-0x7fffffff+L'\0') #endif -#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) +#if __cplusplus >= 201103L #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/src/conf/confstr.c b/system/lib/libc/musl/src/conf/confstr.c index 9c12d365babf2..3d4172846dba9 100644 --- a/system/lib/libc/musl/src/conf/confstr.c +++ b/system/lib/libc/musl/src/conf/confstr.c @@ -6,26 +6,7 @@ size_t confstr(int name, char *buf, size_t len) { const char *s = ""; if (!name) { -#ifndef __EMSCRIPTEN__ s = "/bin:/usr/bin"; -#else - // TODO(sbc): Can we just remove these custom values. - // We have tests that check for them but its not clear - // anything else does. - s = "/"; - } else if (name == _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS) { - s = "POSIX_V6_ILP32_OFF32\nPOSIX_V6_ILP32_OFFBIG"; - } else if (name == _CS_GNU_LIBPTHREAD_VERSION) { - s = ""; - } else if (name == _CS_GNU_LIBC_VERSION) { - s = "glibc 2.14"; - } else if (name == _CS_POSIX_V6_ILP32_OFF32_CFLAGS || - name == _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS || - name == _CS_POSIX_V6_ILP32_OFF32_LDFLAGS) { - s = "-m32"; - } else if (name == _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS) { - s = "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"; -#endif } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>35U) { errno = EINVAL; return 0; diff --git a/system/lib/libc/musl/src/conf/fpathconf.c b/system/lib/libc/musl/src/conf/fpathconf.c index 3161c76ffcab4..e6aca5cffe6f7 100644 --- a/system/lib/libc/musl/src/conf/fpathconf.c +++ b/system/lib/libc/musl/src/conf/fpathconf.c @@ -24,7 +24,7 @@ long fpathconf(int fd, int name) [_PC_REC_MIN_XFER_SIZE] = 4096, [_PC_REC_XFER_ALIGN] = 4096, [_PC_ALLOC_SIZE_MIN] = 4096, - [_PC_SYMLINK_MAX] = 255, // XXX EMSCRIPTEN replace -1 + [_PC_SYMLINK_MAX] = -1, [_PC_2_SYMLINKS] = 1 }; if (name >= sizeof(values)/sizeof(values[0])) { diff --git a/system/lib/libc/musl/src/conf/sysconf.c b/system/lib/libc/musl/src/conf/sysconf.c index a043fe1ac08e1..60d3e745350dc 100644 --- a/system/lib/libc/musl/src/conf/sysconf.c +++ b/system/lib/libc/musl/src/conf/sysconf.c @@ -4,17 +4,10 @@ #include #include #include -#ifndef __EMSCRIPTEN__ #include -#endif #include "syscall.h" #include "libc.h" -#ifdef __EMSCRIPTEN__ -#include "emscripten/heap.h" -#include "emscripten/threading.h" -#endif - #define JT(x) (-256|(x)) #define VER JT(1) #define JT_ARG_MAX JT(2) @@ -36,15 +29,15 @@ long sysconf(int name) { static const short values[] = { [_SC_ARG_MAX] = JT_ARG_MAX, - [_SC_CHILD_MAX] = 1024, // XXX EMSCRIPTEN replace RLIM(NPROC), + [_SC_CHILD_MAX] = RLIM(NPROC), [_SC_CLK_TCK] = 100, [_SC_NGROUPS_MAX] = 32, - [_SC_OPEN_MAX] = 1024, // XXX EMSCRIPTEN replace RLIM(NOFILE), + [_SC_OPEN_MAX] = RLIM(NOFILE), [_SC_STREAM_MAX] = -1, [_SC_TZNAME_MAX] = TZNAME_MAX, [_SC_JOB_CONTROL] = 1, [_SC_SAVED_IDS] = 1, - [_SC_REALTIME_SIGNALS] = 1, + [_SC_REALTIME_SIGNALS] = VER, [_SC_PRIORITY_SCHEDULING] = -1, [_SC_TIMERS] = VER, [_SC_ASYNCHRONOUS_IO] = VER, @@ -61,7 +54,7 @@ long sysconf(int name) [_SC_AIO_LISTIO_MAX] = -1, [_SC_AIO_MAX] = -1, [_SC_AIO_PRIO_DELTA_MAX] = JT_ZERO, /* ?? */ - [_SC_DELAYTIMER_MAX] = _POSIX_DELAYTIMER_MAX, + [_SC_DELAYTIMER_MAX] = JT_DELAYTIMER_MAX, [_SC_MQ_OPEN_MAX] = -1, [_SC_MQ_PRIO_MAX] = JT_MQ_PRIO_MAX, [_SC_VERSION] = VER, @@ -99,10 +92,10 @@ long sysconf(int name) [_SC_THREAD_THREADS_MAX] = -1, [_SC_THREAD_ATTR_STACKADDR] = VER, [_SC_THREAD_ATTR_STACKSIZE] = VER, - [_SC_THREAD_PRIORITY_SCHEDULING] = -1, // XXX EMSCRIPTEN replace VER, + [_SC_THREAD_PRIORITY_SCHEDULING] = VER, [_SC_THREAD_PRIO_INHERIT] = -1, [_SC_THREAD_PRIO_PROTECT] = -1, - [_SC_THREAD_PROCESS_SHARED] = -1, // XXX EMSCRIPTEN replace VER, + [_SC_THREAD_PROCESS_SHARED] = VER, [_SC_NPROCESSORS_CONF] = JT_NPROCESSORS_CONF, [_SC_NPROCESSORS_ONLN] = JT_NPROCESSORS_ONLN, [_SC_PHYS_PAGES] = JT_PHYS_PAGES, @@ -122,8 +115,8 @@ long sysconf(int name) [_SC_XOPEN_XPG4] = -1, [_SC_NZERO] = NZERO, [_SC_XBS5_ILP32_OFF32] = -1, - [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, - [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, + [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, + [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, [_SC_XBS5_LPBIG_OFFBIG] = -1, [_SC_XOPEN_LEGACY] = -1, [_SC_XOPEN_REALTIME] = -1, @@ -152,8 +145,8 @@ long sysconf(int name) [_SC_STREAMS] = JT_ZERO, [_SC_2_PBS_CHECKPOINT] = -1, [_SC_V6_ILP32_OFF32] = -1, - [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, - [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, + [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, + [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, [_SC_V6_LPBIG_OFFBIG] = -1, [_SC_HOST_NAME_MAX] = HOST_NAME_MAX, [_SC_TRACE] = -1, @@ -208,21 +201,14 @@ long sysconf(int name) return DELAYTIMER_MAX; case JT_NPROCESSORS_CONF & 255: case JT_NPROCESSORS_ONLN & 255: ; -#ifdef __EMSCRIPTEN__ - return emscripten_num_logical_cores(); -#else unsigned char set[128] = {1}; int i, cnt; __syscall(SYS_sched_getaffinity, 0, sizeof set, set); for (i=cnt=0; ifd = fd; diff --git a/system/lib/libc/musl/src/env/__environ.c b/system/lib/libc/musl/src/env/__environ.c index fcc881be0da8b..fe8abcf9906a1 100644 --- a/system/lib/libc/musl/src/env/__environ.c +++ b/system/lib/libc/musl/src/env/__environ.c @@ -4,40 +4,3 @@ char **__environ = 0; weak_alias(__environ, ___environ); weak_alias(__environ, _environ); weak_alias(__environ, environ); - -#ifdef __EMSCRIPTEN__ -#include -#include -#include - -// We use emscripten_builtin_malloc here because this memory is never freed and -// and we don't want LSan to consider this a leak. -__attribute__((constructor(100))) // construct this before user code -void __emscripten_environ_constructor(void) { - size_t environ_count; - size_t environ_buf_size; - __wasi_errno_t err = __wasi_environ_sizes_get(&environ_count, - &environ_buf_size); - if (err != __WASI_ERRNO_SUCCESS) { - return; - } - - __environ = emscripten_builtin_malloc(sizeof(char *) * (environ_count + 1)); - if (__environ == 0) { - return; - } - char *environ_buf = emscripten_builtin_malloc(sizeof(char) * environ_buf_size); - if (environ_buf == 0) { - __environ = 0; - return; - } - - // Ensure null termination. - __environ[environ_count] = 0; - - err = __wasi_environ_get((uint8_t**)__environ, environ_buf); - if (err != __WASI_ERRNO_SUCCESS) { - __environ = 0; - } -} -#endif diff --git a/system/lib/libc/musl/src/env/__stack_chk_fail.c b/system/lib/libc/musl/src/env/__stack_chk_fail.c index 94d8e1d4c9604..e53526020f751 100644 --- a/system/lib/libc/musl/src/env/__stack_chk_fail.c +++ b/system/lib/libc/musl/src/env/__stack_chk_fail.c @@ -23,11 +23,6 @@ void __init_ssp(void *entropy) void __stack_chk_fail(void) { -#if defined(__EMSCRIPTEN__) && !defined(NDEBUG) - // Report the reason for the crash, at least in debug builds. - // This is the same message that glibc outputs (even in release builds). - emscripten_err("*** stack smashing detected ***"); -#endif a_crash(); } diff --git a/system/lib/libc/musl/src/errno/__errno_location.c b/system/lib/libc/musl/src/errno/__errno_location.c index 458941368856a..7f9d6027a276a 100644 --- a/system/lib/libc/musl/src/errno/__errno_location.c +++ b/system/lib/libc/musl/src/errno/__errno_location.c @@ -1,20 +1,9 @@ #include #include "pthread_impl.h" -#ifdef __EMSCRIPTEN__ -// For emscripten we use TLS here instead of `__pthread_self`, so that in single -// threaded builds this gets lowered away to normal global variable. -// This also works for WASM_WORKERS there `__pthread_self` does not work. -static _Thread_local int __errno_storage = 0; -#endif - int *__errno_location(void) { -#ifdef __EMSCRIPTEN__ - return &__errno_storage; -#else return &__pthread_self()->errno_val; -#endif } weak_alias(__errno_location, ___errno_location); diff --git a/system/lib/libc/musl/src/errno/__strerror.h b/system/lib/libc/musl/src/errno/__strerror.h index 598af448c5102..14925907b55d3 100644 --- a/system/lib/libc/musl/src/errno/__strerror.h +++ b/system/lib/libc/musl/src/errno/__strerror.h @@ -2,14 +2,8 @@ * This file is included multiple times to declare and define a structure * with these messages, and then to define a lookup table translating * error codes to offsets of corresponding fields in the structure. */ -#if defined(__EMSCRIPTEN__) -/* Error handling is introduced to match the behavior in llvm-libc. - * When invalid errno is specified, Unknown error: errno_code is emitted. - */ -E(0, "Success") -#else + E(0, "No error information") -#endif E(EILSEQ, "Illegal byte sequence") E(EDOM, "Domain error") @@ -22,12 +16,7 @@ E(ENOENT, "No such file or directory") E(ESRCH, "No such process") E(EEXIST, "File exists") -#if defined(__EMSCRIPTEN__) -// This is intended to match the errno in llvm-libc. -E(EOVERFLOW, "Value too large for defined data type") -#else E(EOVERFLOW, "Value too large for data type") -#endif E(ENOSPC, "No space left on device") E(ENOMEM, "Out of memory") @@ -73,11 +62,7 @@ E(ENOLCK, "No locks available") E(EDEADLK, "Resource deadlock would occur") E(ENOTRECOVERABLE, "State not recoverable") -#if defined(__EMSCRIPTEN__) -E(EOWNERDEAD, "Owner died") -#else E(EOWNERDEAD, "Previous owner died") -#endif E(ECANCELED, "Operation canceled") E(ENOSYS, "Function not implemented") E(ENOMSG, "No message of desired type") diff --git a/system/lib/libc/musl/src/errno/strerror.c b/system/lib/libc/musl/src/errno/strerror.c index 0fd1c84289a2e..7f926432b3090 100644 --- a/system/lib/libc/musl/src/errno/strerror.c +++ b/system/lib/libc/musl/src/errno/strerror.c @@ -34,30 +34,14 @@ char *__strerror_l(int e, locale_t loc) if (e==EDQUOT) e=0; else if (e==EDQUOT_ORIG) e=EDQUOT; #endif -#ifdef __EMSCRIPTEN__ - if (e < 0 || e >= sizeof errmsgidx / sizeof *errmsgidx || (e != 0 && !errmsgidx[e])) { - return "Unknown error"; - } - s = (char *)&errmsgstr + errmsgidx[e]; - // strerror is a (debug) dependency of many emscripten syscalls which mean it - // must be excluded from LTO, along with all of its dependencies. - // In order to limit the transitive dependencies we disable localization of - // rrno messages here. - return (char *)s; -#else if (e >= sizeof errmsgidx / sizeof *errmsgidx) e = 0; s = (char *)&errmsgstr + errmsgidx[e]; return (char *)LCTRANS(s, LC_MESSAGES, loc); -#endif } char *strerror(int e) { -#ifdef __EMSCRIPTEN__ - return __strerror_l(e, NULL); -#else return __strerror_l(e, CURRENT_LOCALE); -#endif } weak_alias(__strerror_l, strerror_l); diff --git a/system/lib/libc/musl/src/exit/_Exit.c b/system/lib/libc/musl/src/exit/_Exit.c index 9d06aac1d89ef..7a6115c7bbc71 100644 --- a/system/lib/libc/musl/src/exit/_Exit.c +++ b/system/lib/libc/musl/src/exit/_Exit.c @@ -3,10 +3,6 @@ _Noreturn void _Exit(int ec) { -#ifdef __EMSCRIPTEN__ - __wasi_proc_exit(ec); -#else __syscall(SYS_exit_group, ec); for (;;) __syscall(SYS_exit, ec); -#endif } diff --git a/system/lib/libc/musl/src/exit/abort.c b/system/lib/libc/musl/src/exit/abort.c index a6427d51d66e9..f21f458eca149 100644 --- a/system/lib/libc/musl/src/exit/abort.c +++ b/system/lib/libc/musl/src/exit/abort.c @@ -6,20 +6,8 @@ #include "lock.h" #include "ksigaction.h" -#if __EMSCRIPTEN__ -#include "emscripten_internal.h" -#endif - _Noreturn void abort(void) { -#if __EMSCRIPTEN__ - /* In emscripten we call out to JS to perform the actual abort where it can - * produce a nice error. - * Note that the JS library function is not called `abort` to avoid conflict - * with the JavaScript abort helper (which takes a JS string as an argument - * and is itself used to implement `_abort_js`) */ - _abort_js(); -#else raise(SIGABRT); /* If there was a SIGABRT handler installed and it returned, or if @@ -39,5 +27,4 @@ _Noreturn void abort(void) a_crash(); raise(SIGKILL); _Exit(127); -#endif } diff --git a/system/lib/libc/musl/src/exit/atexit.c b/system/lib/libc/musl/src/exit/atexit.c index f2401780b30e5..854e9fddbe559 100644 --- a/system/lib/libc/musl/src/exit/atexit.c +++ b/system/lib/libc/musl/src/exit/atexit.c @@ -36,11 +36,11 @@ void __funcs_on_exit() } } -void ___cxa_finalize(void *dso) +void __cxa_finalize(void *dso) { } -int ___cxa_atexit(void (*func)(void *), void *arg, void *dso) +int __cxa_atexit(void (*func)(void *), void *arg, void *dso) { LOCK(lock); @@ -73,13 +73,7 @@ static void call(void *p) ((void (*)(void))(uintptr_t)p)(); } -int __atexit(void (*func)(void)) +int atexit(void (*func)(void)) { - return ___cxa_atexit(call, (void *)(uintptr_t)func, 0); + return __cxa_atexit(call, (void *)(uintptr_t)func, 0); } - -// XXX: EMSCRIPTEN: Use weak aliases here so that we can override these symbols -// in when EXIT_RUNTIME is set to 0. -weak_alias(__atexit, atexit); -weak_alias(___cxa_atexit, __cxa_atexit); -weak_alias(___cxa_finalize, __cxa_finalize); diff --git a/system/lib/libc/musl/src/fcntl/fcntl.c b/system/lib/libc/musl/src/fcntl/fcntl.c index dbc913ba703a5..d3bff5c486808 100644 --- a/system/lib/libc/musl/src/fcntl/fcntl.c +++ b/system/lib/libc/musl/src/fcntl/fcntl.c @@ -3,65 +3,37 @@ #include #include #include "syscall.h" -#include int fcntl(int fd, int cmd, ...) { -#ifdef __EMSCRIPTEN__ - // XXX Emscripten: According to the va_arg man page it is undefined behaviour to - // read arguments that are not passed. This can lead to a false positive - // in SAFE_HEAP, so avoid it. - unsigned long arg = 0; - if (cmd != F_GETFL && cmd != F_GETFD && cmd != F_GETOWN) { - va_list ap; - va_start(ap, cmd); - arg = va_arg(ap, unsigned long); - va_end(ap); - } -#else unsigned long arg; va_list ap; va_start(ap, cmd); arg = va_arg(ap, unsigned long); va_end(ap); -#endif if (cmd == F_SETFL) arg |= O_LARGEFILE; if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg); if (cmd == F_GETOWN) { struct f_owner_ex ex; int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex); -#ifdef __EMSCRIPTEN__ - // XXX Emscripten: Mirror the behaviour/limitation of glibc which - // will misinterpret negative PIDs in range of -1 to -4095 as being - // errno values. - if (ret == -EINVAL) ret = __syscall(SYS_fcntl, fd, cmd, (void *)arg); -#else if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg); -#endif if (ret) return __syscall_ret(ret); return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; } if (cmd == F_DUPFD_CLOEXEC) { int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); if (ret != -EINVAL) { -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process - if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); -#endif + if (ret >= 0) + __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); return __syscall_ret(ret); } ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0); if (ret != -EINVAL) { -#ifdef __EMSCRIPTEN__ - if (ret >= 0) __wasi_fd_close(ret); -#else if (ret >= 0) __syscall(SYS_close, ret); -#endif return __syscall_ret(-EINVAL); } ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg); -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); -#endif return __syscall_ret(ret); } switch (cmd) { diff --git a/system/lib/libc/musl/src/fcntl/open.c b/system/lib/libc/musl/src/fcntl/open.c index b95a90e017274..4c3c82759c1b2 100644 --- a/system/lib/libc/musl/src/fcntl/open.c +++ b/system/lib/libc/musl/src/fcntl/open.c @@ -14,10 +14,8 @@ int open(const char *filename, int flags, ...) } int fd = __sys_open_cp(filename, flags, mode); -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (fd>=0 && (flags & O_CLOEXEC)) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); -#endif return __syscall_ret(fd); } diff --git a/system/lib/libc/musl/src/internal/atomic.h b/system/lib/libc/musl/src/internal/atomic.h index 8f71c8cdf75c0..96c1552d6eda6 100644 --- a/system/lib/libc/musl/src/internal/atomic.h +++ b/system/lib/libc/musl/src/internal/atomic.h @@ -194,7 +194,7 @@ static inline void a_store(volatile int *p, int v) #ifndef a_barrier #define a_barrier a_barrier -static inline void a_barrier() +static void a_barrier() { volatile int tmp = 0; a_cas(&tmp, 0, 0); diff --git a/system/lib/libc/musl/src/internal/dynlink.h b/system/lib/libc/musl/src/internal/dynlink.h index 55482cf5f7959..40c743e2fcbe0 100644 --- a/system/lib/libc/musl/src/internal/dynlink.h +++ b/system/lib/libc/musl/src/internal/dynlink.h @@ -7,40 +7,6 @@ #include #include -#ifdef __EMSCRIPTEN__ -// Declare `struct dso` in this header so that it is visible to gen_struct_info. - -#include - -struct dso { - // Pointer back to the dlevent in the event sequence which loaded this DSO. - struct dlevent* event; - - // Flags used to open the library. We need to cache these so that other - // threads can mirror the open library state. - int flags; - - // Location in memory/table of static data/static function addresses - // The first thread to load a given module alloces the memory and table - // address space and then sets this field to non-zero. - uint8_t mem_allocated; - void* mem_addr; - size_t mem_size; - void* table_addr; - size_t table_size; - - // For DSO load events, where the DSO comes from a file on disc, this - // is a pointer the file data read in by the laoding thread and shared with - // others. - uint8_t* file_data; - size_t file_data_size; - - // Flexible array; must be final element of struct - char name[]; -}; - -#else - #if UINTPTR_MAX == 0xffffffff typedef Elf32_Ehdr Ehdr; typedef Elf32_Phdr Phdr; @@ -139,8 +105,6 @@ struct fdpic_dummy_loadmap { typedef void (*stage2_func)(unsigned char *, size_t *); -#endif // __EMSCRIPTEN__ - hidden void *__dlsym(void *restrict, const char *restrict, void *restrict); hidden void __dl_seterr(const char *, ...); diff --git a/system/lib/libc/musl/src/internal/libc.c b/system/lib/libc/musl/src/internal/libc.c index c84ed3d2524c1..cb05181084a57 100644 --- a/system/lib/libc/musl/src/internal/libc.c +++ b/system/lib/libc/musl/src/internal/libc.c @@ -3,9 +3,7 @@ struct __libc __libc; size_t __hwcap; -#ifndef __EMSCRIPTEN__ char *__progname=0, *__progname_full=0; weak_alias(__progname, program_invocation_short_name); weak_alias(__progname_full, program_invocation_name); -#endif diff --git a/system/lib/libc/musl/src/internal/libc.h b/system/lib/libc/musl/src/internal/libc.h index b0b3f20cf6a4c..619bba8613e8d 100644 --- a/system/lib/libc/musl/src/internal/libc.h +++ b/system/lib/libc/musl/src/internal/libc.h @@ -4,7 +4,6 @@ #include #include #include -#include struct __locale_map; @@ -54,11 +53,6 @@ extern char *__progname, *__progname_full; extern hidden const char __libc_version[]; hidden void __synccall(void (*)(void *), void *); -#ifdef __EMSCRIPTEN__ -hidden int __setxid_emscripten(); -#define __setxid(a, b, c, d) __setxid_emscripten() -#else hidden int __setxid(int, int, int, int); -#endif #endif diff --git a/system/lib/libc/musl/src/internal/libm.h b/system/lib/libc/musl/src/internal/libm.h index a47208aa6ad3c..72ad17d8ebe80 100644 --- a/system/lib/libc/musl/src/internal/libm.h +++ b/system/lib/libc/musl/src/internal/libm.h @@ -177,13 +177,6 @@ static inline void fp_force_evall(long double x) } #endif -#ifdef __EMSCRIPTEN__ -/* - * asm.js doesn't have user-accessible floating point exceptions, so there's - * no point in trying to force expression evaluations to produce them. - */ -#define FORCE_EVAL(x) -#else #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ fp_force_evalf(x); \ @@ -193,7 +186,6 @@ static inline void fp_force_evall(long double x) fp_force_evall(x); \ } \ } while(0) -#endif #define asuint(f) ((union{float _f; uint32_t _i;}){f})._i #define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f diff --git a/system/lib/libc/musl/src/internal/locale_impl.h b/system/lib/libc/musl/src/internal/locale_impl.h index 9a7b07c4aac0e..4431a92eb7112 100644 --- a/system/lib/libc/musl/src/internal/locale_impl.h +++ b/system/lib/libc/musl/src/internal/locale_impl.h @@ -31,31 +31,15 @@ hidden char *__gettextdomain(void); #define LOC_MAP_FAILED ((const struct __locale_map *)-1) -#if __EMSCRIPTEN__ -// Disable message translation completely under emscripten since we don't -// support loading any actual locale data, and even looking up the current -// local via CURRENT_LOCALE via TLS is not free. -#define LCTRANS(msg, lc, loc) msg -#define LCTRANS_CUR(msg) msg -#else #define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)]) #define LCTRANS_CUR(msg) __lctrans_cur(msg) -#endif #define C_LOCALE ((locale_t)&__c_locale) #define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale) -#ifdef __EMSCRIPTEN__ -extern _Thread_local locale_t __tls_locale; - -#define CURRENT_LOCALE (__tls_locale) - -#define CURRENT_UTF8 (!!__tls_locale->cat[LC_CTYPE]) -#else #define CURRENT_LOCALE (__pthread_self()->locale) #define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE]) -#endif #undef MB_CUR_MAX #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1) diff --git a/system/lib/libc/musl/src/internal/progname.c b/system/lib/libc/musl/src/internal/progname.c deleted file mode 100644 index ffefb792e6989..0000000000000 --- a/system/lib/libc/musl/src/internal/progname.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2022 The Emscripten Authors. All rights reserved. - * Emscripten is available under two separate licenses, the MIT license and the - * University of Illinois/NCSA Open Source License. Both these licenses can be - * found in the LICENSE file. - */ - -#ifdef __EMSCRIPTEN__ -#include -#include - -#include "emscripten_internal.h" - -char *__progname=0, *__progname_full=0; - -weak_alias(__progname, program_invocation_short_name); -weak_alias(__progname_full, program_invocation_name); - -__attribute__((constructor)) -static void __progname_ctor(void) -{ - static char full_path[PATH_MAX]; - char *basename; - - _emscripten_get_progname(full_path, sizeof(full_path)); - - basename = strrchr(full_path, '/'); - if (basename == NULL) { - basename = full_path; - } else { - basename++; - } - - __progname_full = full_path; - __progname = basename; -} -#endif diff --git a/system/lib/libc/musl/src/internal/proxying_notification_state.h b/system/lib/libc/musl/src/internal/proxying_notification_state.h deleted file mode 100644 index 37a648315c003..0000000000000 --- a/system/lib/libc/musl/src/internal/proxying_notification_state.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2022 The Emscripten Authors. All rights reserved. - * Emscripten is available under two separate licenses, the MIT license and the - * University of Illinois/NCSA Open Source License. Both these licenses can be - * found in the LICENSE file. - */ - -#pragma once - -// Flag values used when creating postMessage notifications and when freeing -// proxying queues. New postMessages are created for new work unless the -// relevant task queue is in state NOTIFICATION_PENDING and proxying queues can -// only be freed when all of their task queues are in NOTIFICATION_NONE state. -typedef enum notification_state { - NOTIFICATION_NONE = 0, - NOTIFICATION_RECEIVED = 1, - NOTIFICATION_PENDING = 2, -} notification_state; diff --git a/system/lib/libc/musl/src/internal/pthread_impl.h b/system/lib/libc/musl/src/internal/pthread_impl.h index a366b6cef8eb3..de2b9d8b477e6 100644 --- a/system/lib/libc/musl/src/internal/pthread_impl.h +++ b/system/lib/libc/musl/src/internal/pthread_impl.h @@ -9,12 +9,6 @@ #include "libc.h" #include "syscall.h" #include "atomic.h" -#ifdef __EMSCRIPTEN__ -#include "em_task_queue.h" -#include "thread_mailbox.h" -#include "threading_internal.h" -#include -#endif #include "futex.h" #include "pthread_arch.h" @@ -39,10 +33,7 @@ struct pthread { /* Part 2 -- implementation details, non-ABI. */ int tid; -#ifndef __EMSCRIPTEN__ - // Emscripten uses C11 _Thread_local instead for errno int errno_val; -#endif volatile int detach_state; volatile int cancel; volatile unsigned char canceldisable, cancelasync; @@ -63,10 +54,7 @@ struct pthread { } robust_list; int h_errno_val; volatile int timer_id; -#ifndef __EMSCRIPTEN__ - // Emscripten uses C11 _Thread_local instead for locale locale_t locale; -#endif volatile int killlock[1]; char *dlerror_buf; void *stdio_locks; @@ -77,59 +65,10 @@ struct pthread { uintptr_t canary; uintptr_t *dtv; #endif - -// XXX Emscripten: Need some custom thread control structures. -#ifdef __EMSCRIPTEN__ - // If --threadprofiler is enabled, this pointer is allocated to contain - // internal information about the thread state for profiling purposes. - thread_profiler_block * _Atomic profilerBlock; - // The TLS base to use the main module TLS data. Secondary modules - // still require dynamic allocation. - void* tls_base; - // The lowest level of the proxying system. Other threads can enqueue - // messages on the mailbox and notify this thread to asynchronously - // process them once it returns to its event loop. When this thread is - // shut down, the mailbox is closed (see below) to prevent further - // messages from being enqueued and all the remaining queued messages - // are dequeued and their shutdown handlers are executed. This allows - // other threads waiting for their messages to be processed to be - // notified that their messages will not be processed after all. - em_task_queue* mailbox; - // To ensure that no other thread is concurrently enqueueing a message - // when this thread shuts down, maintain an atomic refcount. Enqueueing - // threads atomically increment the count from a nonzero number to - // acquire the mailbox and decrement the count when they finish. When - // this thread shuts down it will atomically decrement the count and - // wait until it reaches 0, at which point the mailbox is considered - // closed and no further messages will be enqueued. - _Atomic int mailbox_refcount; - // Whether the thread has executed an `Atomics.waitAsync` on this - // pthread struct and can be notified of new mailbox messages via - // `Atomics.notify`. Otherwise, such as when the environment does not - // implement `Atomics.waitAsync` or when the thread has not had a chance - // to initialize itself yet, the notification has to fall back to the - // postMessage path. Once this becomes true, it remains true so we never - // fall back to postMessage unnecessarily. - _Atomic int waiting_async; - // The address the thread is currently waiting on in emscripten_futex_wait. - // - // This field encodes the state using the following bitmask: - // - NULL: Not waiting, no pending notification. - // - NOTIFY_BIT (0x1): Not waiting, but a notification was sent. - // - addr: Waiting on `addr`, no pending notification. - // - addr | NOTIFY_BIT: Waiting on `addr`, notification sent. - // - // Since futex addresses must be 4-byte aligned, the low bit is safe to use. - _Atomic uintptr_t wait_addr; -#endif }; -#ifdef __EMSCRIPTEN__ -#define NOTIFY_BIT (1 << 0) -#endif - enum { - DT_EXITED, + DT_EXITED = 0, DT_EXITING, DT_JOINABLE, DT_DETACHED, @@ -160,12 +99,6 @@ enum { #define _rw_lock __u.__vi[0] #define _rw_waiters __u.__vi[1] #define _rw_shared __u.__i[2] -#ifdef __EMSCRIPTEN__ -// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, so use an extra field -// _rw_wr_owner to record which thread owns the write lock in order to avoid hangs. -// Points to the pthread that currently has the write lock. -#define _rw_wr_owner __u.__vi[3] -#endif #define _b_lock __u.__vi[0] #define _b_waiters __u.__vi[1] #define _b_limit __u.__i[2] @@ -236,22 +169,14 @@ static inline void __wake(volatile void *addr, int cnt, int priv) { if (priv) priv = FUTEX_PRIVATE; if (cnt<0) cnt = INT_MAX; -#ifdef __EMSCRIPTEN__ - emscripten_futex_wake(addr, (cnt)<0?INT_MAX:(cnt)); -#else __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); -#endif } static inline void __futexwait(volatile void *addr, int val, int priv) { -#ifdef __EMSCRIPTEN__ - __wait(addr, NULL, val, priv); -#else if (priv) priv = FUTEX_PRIVATE; __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); -#endif } hidden void __acquire_ptc(void); @@ -269,13 +194,7 @@ extern hidden volatile int __abort_lock[1]; extern hidden unsigned __default_stacksize; extern hidden unsigned __default_guardsize; - -#ifdef __EMSCRIPTEN__ -// Keep in sync with DEFAULT_PTHREAD_STACK_SIZE in settings.js -#define DEFAULT_STACK_SIZE (64*1024) -#else #define DEFAULT_STACK_SIZE 131072 -#endif #define DEFAULT_GUARD_SIZE 8192 #define DEFAULT_STACK_MAX (8<<20) @@ -283,13 +202,4 @@ extern hidden unsigned __default_guardsize; #define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1) -#ifdef __EMSCRIPTEN_SHARED_MEMORY__ -pid_t gettid(void); -// Unlike `__pthread_self()->tid, `gettid` works under both wasm workers and -// pthreads. -#define CURRENT_THREAD_ID gettid() -#else -#define CURRENT_THREAD_ID __pthread_self()->tid -#endif - #endif diff --git a/system/lib/libc/musl/src/internal/stdio_impl.h b/system/lib/libc/musl/src/internal/stdio_impl.h index 3dded20e50149..0b2438d613fe9 100644 --- a/system/lib/libc/musl/src/internal/stdio_impl.h +++ b/system/lib/libc/musl/src/internal/stdio_impl.h @@ -6,15 +6,9 @@ #define UNGET 8 -#if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_SHARED_MEMORY__) -#define FFINALLOCK(f) -#define FLOCK(f) -#define FUNLOCK(f) -#else #define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0) #define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0) #define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0) -#endif #define F_PERM 1 #define F_NORD 4 @@ -72,7 +66,7 @@ hidden int __towrite(FILE *); hidden void __stdio_exit(void); hidden void __stdio_exit_needed(void); -#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303) && !defined(__EMSCRIPTEN__) +#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303) __attribute__((visibility("protected"))) #endif int __overflow(FILE *, int), __uflow(FILE *); @@ -115,12 +109,4 @@ hidden void __getopt_msg(const char *, const char *, const char *, size_t); hidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t); hidden int __fclose_ca(FILE *); -// XXX EMSCRIPTEN -extern int vfiprintf(FILE *restrict f, const char *restrict fmt, va_list ap); -extern int vsiprintf(char *restrict s, const char *restrict fmt, va_list ap); -extern int vsniprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); -extern int __small_vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap); -extern int __small_vsprintf(char *restrict s, const char *restrict fmt, va_list ap); -extern int __small_vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); - #endif diff --git a/system/lib/libc/musl/src/internal/syscall.h b/system/lib/libc/musl/src/internal/syscall.h index 1a6c4313852d7..33d981f986506 100644 --- a/system/lib/libc/musl/src/internal/syscall.h +++ b/system/lib/libc/musl/src/internal/syscall.h @@ -19,44 +19,21 @@ #endif #ifndef __scc -#ifdef __EMSCRIPTEN__ -// With emscripten we allow the passing of longer-than-word-sized -// argument (such as off_t on wasm32) and let binaryen handle splitting -// them into a pair of i32 arguments. -#define __scc(X) ((long long) (X)) -#else #define __scc(X) ((long) (X)) -#endif typedef long syscall_arg_t; #endif -#ifdef __cplusplus -extern "C" { -#endif hidden long __syscall_ret(unsigned long), __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t); -#ifdef __cplusplus -} -#endif -#ifndef __EMSCRIPTEN__ #define __syscall1(n,a) __syscall1(n,__scc(a)) #define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) #define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) #define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) #define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) #define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#else // __EMSCRIPTEN__ -#define __syscall_emscripten(n, ...) n(__VA_ARGS__) -#define __syscall_emscripten0(n) __syscall_emscripten(n) -#define __syscall_emscripten1(n,a) __syscall_emscripten(n,__scc(a)) -#define __syscall_emscripten2(n,a,b) __syscall_emscripten(n,__scc(a),__scc(b)) -#define __syscall_emscripten3(n,a,b,c) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c)) -#define __syscall_emscripten4(n,a,b,c,d) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d)) -#define __syscall_emscripten5(n,a,b,c,d,e) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) -#define __syscall_emscripten6(n,a,b,c,d,e,f) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#endif // __EMSCRIPTEN__ +#define __syscall7(n,a,b,c,d,e,f,g) __syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g)) #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,) @@ -64,18 +41,12 @@ hidden long __syscall_ret(unsigned long), #define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b) #define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) -#ifndef __EMSCRIPTEN__ #define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) -#else -#define __syscall(...) __SYSCALL_DISP(__syscall_emscripten,__VA_ARGS__) -#endif - #define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) #define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f)) #define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f)) -#ifndef __EMSCRIPTEN__ #define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0) #define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0) #define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0) @@ -85,16 +56,9 @@ hidden long __syscall_ret(unsigned long), #define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) -#else // __EMSCRIPTEN__ -#define __syscall_cp(...) __syscall(__VA_ARGS__) -#endif // __EMSCRIPTEN__ - #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) -#ifdef __EMSCRIPTEN__ -#define __socketcall(nm,a,b,c,d,e,f) __syscall(SYS_##nm, a, b, c, d, e, f) -#define __socketcall_cp(nm,a,b,c,d,e,f) __syscall_cp(SYS_##nm, a, b, c, d, e, f) -#else +static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f) { long r; if (cp) r = __syscall_cp(sys, a, b, c, d, e, f); @@ -110,7 +74,6 @@ hidden long __syscall_ret(unsigned long), __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) #define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \ __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) -#endif /* fixup legacy 16-bit junk */ @@ -134,6 +97,7 @@ hidden long __syscall_ret(unsigned long), #undef SYS_setgid #undef SYS_setfsuid #undef SYS_setfsgid +#define SYS_lchown SYS_lchown32 #define SYS_getuid SYS_getuid32 #define SYS_getgid SYS_getgid32 #define SYS_geteuid SYS_geteuid32 @@ -147,6 +111,7 @@ hidden long __syscall_ret(unsigned long), #define SYS_getresuid SYS_getresuid32 #define SYS_setresgid SYS_setresgid32 #define SYS_getresgid SYS_getresgid32 +#define SYS_chown SYS_chown32 #define SYS_setuid SYS_setuid32 #define SYS_setgid SYS_setgid32 #define SYS_setfsuid SYS_setfsuid32 @@ -408,7 +373,6 @@ hidden long __syscall_ret(unsigned long), #define SIOCGSTAMPNS_OLD 0x8907 #endif -#ifndef __EMSCRIPTEN__ #ifdef SYS_open #define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) #define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) @@ -420,12 +384,6 @@ hidden long __syscall_ret(unsigned long), #define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) #define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) #endif -#else // __EMSCRIPTEN__ -#define __sys_open2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) -#define __sys_open3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) -#define __sys_open_cp2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) -#define __sys_open_cp3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) -#endif #define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__) #define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__)) @@ -445,11 +403,7 @@ hidden long __emulate_wait4(int, int *, int, void *, int); #define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d)) #define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d)) -#ifdef __cplusplus -hidden void __procfdname(char __buf[], unsigned); -#else hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); -#endif hidden void *__vdsosym(const char *, const char *); diff --git a/system/lib/libc/musl/src/linux/gettid.c b/system/lib/libc/musl/src/linux/gettid.c index cd401dd52a3cd..70767137e92fe 100644 --- a/system/lib/libc/musl/src/linux/gettid.c +++ b/system/lib/libc/musl/src/linux/gettid.c @@ -2,35 +2,7 @@ #include #include "pthread_impl.h" -#ifdef __EMSCRIPTEN__ -weak int emscripten_wasm_worker_self_id(); -#endif - -#if defined(__EMSCRIPTEN_WASM_WORKERS__) && defined(__EMSCRIPTEN_PTHREADS__) -#error "this file should be compiled with either wasm workers or pthreads but not both" -#endif - pid_t gettid(void) { -#ifdef __EMSCRIPTEN_WASM_WORKERS__ - // Offset the worker ID by 1 so we never return 0 from this function. - // Strangly we cannot assume the existence of emscripten_wasm_worker_self_id - // here because libc-ww is also used for `-sSHARED_MEMORY` builds (without - // libwasm_workers linked in. - if (emscripten_wasm_worker_self_id) { - return emscripten_wasm_worker_self_id() + 1; - } else { - return 42; - } -#else -#if defined(__EMSCRIPTEN_PTHREADS__) - // The pthread-variant of libc can also be used alongside wasm workers. - // We detect that via a weak reference to the self_id function. - if (emscripten_wasm_worker_self_id) { - pid_t rtn = emscripten_wasm_worker_self_id(); - if (rtn) return rtn; - } -#endif return __pthread_self()->tid; -#endif } diff --git a/system/lib/libc/musl/src/linux/sbrk.c b/system/lib/libc/musl/src/linux/sbrk.c index 8e3a9b6645d68..bb86630584441 100644 --- a/system/lib/libc/musl/src/linux/sbrk.c +++ b/system/lib/libc/musl/src/linux/sbrk.c @@ -1,4 +1,3 @@ -#if !__EMSCRIPTEN__ /* Emscripten controls sbrk itself */ #define _BSD_SOURCE #include #include @@ -10,5 +9,3 @@ void *sbrk(intptr_t inc) if (inc) return (void *)__syscall_ret(-ENOMEM); return (void *)__syscall(SYS_brk, 0); } -#endif - diff --git a/system/lib/libc/musl/src/linux/statx.c b/system/lib/libc/musl/src/linux/statx.c index 0245e34608bcd..4616bff4aadfc 100644 --- a/system/lib/libc/musl/src/linux/statx.c +++ b/system/lib/libc/musl/src/linux/statx.c @@ -7,9 +7,6 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx) { -#ifdef __EMSCRIPTEN__ - int ret; -#else int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx); #ifndef SYS_fstatat @@ -17,7 +14,6 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct #endif if (ret != -ENOSYS) return __syscall_ret(ret); -#endif struct stat st; ret = fstatat(dirfd, path, &st, flags); diff --git a/system/lib/libc/musl/src/locale/catclose.c b/system/lib/libc/musl/src/locale/catclose.c index 6f4f77037d2f1..54e24dd2163bc 100644 --- a/system/lib/libc/musl/src/locale/catclose.c +++ b/system/lib/libc/musl/src/locale/catclose.c @@ -8,9 +8,7 @@ int catclose (nl_catd catd) { -#ifndef __EMSCRIPTEN__ char *map = (char *)catd; munmap(map, V(map+8)+20); -#endif return 0; } diff --git a/system/lib/libc/musl/src/locale/catgets.c b/system/lib/libc/musl/src/locale/catgets.c index b7caaf01e3c7b..71c31c1d6d010 100644 --- a/system/lib/libc/musl/src/locale/catgets.c +++ b/system/lib/libc/musl/src/locale/catgets.c @@ -5,7 +5,6 @@ #include #include -#ifndef __EMSCRIPTEN__ #define V(p) be32toh(*(uint32_t *)(p)) static int cmp(const void *a, const void *b) @@ -13,13 +12,9 @@ static int cmp(const void *a, const void *b) uint32_t x = V(a), y = V(b); return xy ? 1 : 0; } -#endif char *catgets (nl_catd catd, int set_id, int msg_id, const char *s) { -#ifdef __EMSCRIPTEN__ - return (char *)s; -#else const char *map = (const char *)catd; uint32_t nsets = V(map+4); const char *sets = map+20; @@ -40,5 +35,4 @@ char *catgets (nl_catd catd, int set_id, int msg_id, const char *s) return (char *)s; } return (char *)(strings + V(msg+8)); -#endif } diff --git a/system/lib/libc/musl/src/locale/catopen.c b/system/lib/libc/musl/src/locale/catopen.c index 5bf2e9031dadf..97f2446d37f98 100644 --- a/system/lib/libc/musl/src/locale/catopen.c +++ b/system/lib/libc/musl/src/locale/catopen.c @@ -9,7 +9,6 @@ #include #include "libc.h" -#ifndef __EMSCRIPTEN__ #define V(p) be32toh(*(uint32_t *)(p)) static nl_catd do_catopen(const char *name) @@ -25,11 +24,9 @@ static nl_catd do_catopen(const char *name) } return (nl_catd)map; } -#endif nl_catd catopen(const char *name, int oflag) { -#ifndef __EMSCRIPTEN__ nl_catd catd; if (strchr(name, '/')) return do_catopen(name); @@ -78,6 +75,5 @@ nl_catd catopen(const char *name, int oflag) if (catd != (nl_catd)-1) return catd; } errno = ENOENT; -#endif return (nl_catd)-1; } diff --git a/system/lib/libc/musl/src/locale/dcngettext.c b/system/lib/libc/musl/src/locale/dcngettext.c index 56bee9931d146..0b53286db7536 100644 --- a/system/lib/libc/musl/src/locale/dcngettext.c +++ b/system/lib/libc/musl/src/locale/dcngettext.c @@ -189,7 +189,7 @@ char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, snprintf(name, sizeof name, "%s/%.*s%.*s/%s/%s.mo\0", dirname, (int)loclen, locname, (int)alt_modlen, modname, catname, domainname); - if ((map = __map_file(name, &map_size))) break; + if (map = __map_file(name, &map_size)) break; /* Try dropping @mod, _YY, then both. */ if (alt_modlen) { diff --git a/system/lib/libc/musl/src/locale/iconv.c b/system/lib/libc/musl/src/locale/iconv.c index 3dd9fd902e09d..175def1c63f1a 100644 --- a/system/lib/libc/musl/src/locale/iconv.c +++ b/system/lib/libc/musl/src/locale/iconv.c @@ -495,7 +495,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (c >= 93 || d >= 94) { c += (0xa1-0x81); d += 0xa1; - if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52) + if (c >= 93 || c>=0xc6-0x81 && d>0x52) goto ilseq; if (d-'A'<26) d = d-'A'; else if (d-'a'<26) d = d-'a'+26; @@ -538,10 +538,6 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (*outb < k) goto toobig; memcpy(*out, tmp, k); } else k = wctomb_utf8(*out, c); - /* This failure condition should be unreachable, but - * is included to prevent decoder bugs from translating - * into advancement outside the output buffer range. */ - if (k>4) goto ilseq; *out += k; *outb -= k; break; diff --git a/system/lib/libc/musl/src/locale/locale_map.c b/system/lib/libc/musl/src/locale/locale_map.c index d696066cd3287..da61f7fc032c5 100644 --- a/system/lib/libc/musl/src/locale/locale_map.c +++ b/system/lib/libc/musl/src/locale/locale_map.c @@ -12,14 +12,12 @@ #define realloc undef #define free undef -#ifndef __EMSCRIPTEN__ const char *__lctrans_impl(const char *msg, const struct __locale_map *lm) { const char *trans = 0; if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg); return trans ? trans : msg; } -#endif static const char envvars[][12] = { "LC_CTYPE", @@ -65,7 +63,6 @@ const struct __locale_map *__get_locale(int cat, const char *val) for (p=loc_head; p; p=p->next) if (!strcmp(val, p->name)) return p; -#ifndef __EMSCRIPTEN__ // don't support MUSL_LOCPATH which uses mmap if (!libc.secure) path = getenv("MUSL_LOCPATH"); /* FIXME: add a default path? */ @@ -94,7 +91,6 @@ const struct __locale_map *__get_locale(int cat, const char *val) break; } } -#endif /* If no locale definition was found, make a locale map * object anyway to store the name, which is kept for the diff --git a/system/lib/libc/musl/src/locale/uselocale.c b/system/lib/libc/musl/src/locale/uselocale.c index c7b68b5a0d14e..0fc5ecbc07f29 100644 --- a/system/lib/libc/musl/src/locale/uselocale.c +++ b/system/lib/libc/musl/src/locale/uselocale.c @@ -2,24 +2,13 @@ #include "pthread_impl.h" #include "libc.h" -#ifdef __EMSCRIPTEN__ -_Thread_local locale_t __tls_locale = &libc.global_locale; -#endif - locale_t __uselocale(locale_t new) { -#ifdef __EMSCRIPTEN__ - locale_t old = __tls_locale; - locale_t global = &libc.global_locale; - - if (new) __tls_locale = new == LC_GLOBAL_LOCALE ? global : new; -#else pthread_t self = __pthread_self(); locale_t old = self->locale; locale_t global = &libc.global_locale; if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new; -#endif return old == global ? LC_GLOBAL_LOCALE : old; } diff --git a/system/lib/libc/musl/src/malloc/reallocarray.c b/system/lib/libc/musl/src/malloc/reallocarray.c deleted file mode 100644 index bcf5f4346d0fb..0000000000000 --- a/system/lib/libc/musl/src/malloc/reallocarray.c +++ /dev/null @@ -1,17 +0,0 @@ -#define _BSD_SOURCE -#include -#include - -#ifdef __EMSCRIPTEN__ -/* Must be weak so that lsan can override */ -weak -#endif -void *reallocarray(void *ptr, size_t m, size_t n) -{ - if (n && m > -1 / n) { - errno = ENOMEM; - return 0; - } - - return realloc(ptr, m * n); -} diff --git a/system/lib/libc/musl/src/math/ceil.c b/system/lib/libc/musl/src/math/ceil.c index 93265657d3585..b13e6f2d63689 100644 --- a/system/lib/libc/musl/src/math/ceil.c +++ b/system/lib/libc/musl/src/math/ceil.c @@ -1,21 +1,14 @@ #include "libm.h" -#ifndef __wasm__ #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON #endif static const double_t toint = 1/EPS; -#endif double ceil(double x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_ceil(x); -#else union {double f; uint64_t i;} u = {x}; int e = u.i >> 52 & 0x7ff; double_t y; @@ -35,5 +28,4 @@ double ceil(double x) if (y < 0) return x + y + 1; return x + y; -#endif } diff --git a/system/lib/libc/musl/src/math/ceilf.c b/system/lib/libc/musl/src/math/ceilf.c index 9a071337029a7..869835f397838 100644 --- a/system/lib/libc/musl/src/math/ceilf.c +++ b/system/lib/libc/musl/src/math/ceilf.c @@ -2,11 +2,6 @@ float ceilf(float x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_ceilf(x); -#else union {float f; uint32_t i;} u = {x}; int e = (int)(u.i >> 23 & 0xff) - 0x7f; uint32_t m; @@ -29,5 +24,4 @@ float ceilf(float x) u.f = 1.0; } return u.f; -#endif } diff --git a/system/lib/libc/musl/src/math/copysign.c b/system/lib/libc/musl/src/math/copysign.c index 1fc78c9f23ad1..b09331b6876e7 100644 --- a/system/lib/libc/musl/src/math/copysign.c +++ b/system/lib/libc/musl/src/math/copysign.c @@ -1,14 +1,8 @@ #include "libm.h" double copysign(double x, double y) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_copysign(x, y); -#else union {double f; uint64_t i;} ux={x}, uy={y}; ux.i &= -1ULL/2; ux.i |= uy.i & 1ULL<<63; return ux.f; -#endif } diff --git a/system/lib/libc/musl/src/math/copysignf.c b/system/lib/libc/musl/src/math/copysignf.c index 76d2d255dcf82..0af6ae9b2155d 100644 --- a/system/lib/libc/musl/src/math/copysignf.c +++ b/system/lib/libc/musl/src/math/copysignf.c @@ -3,14 +3,8 @@ float copysignf(float x, float y) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_copysignf(x, y); -#else union {float f; uint32_t i;} ux={x}, uy={y}; ux.i &= 0x7fffffff; ux.i |= uy.i & 0x80000000; return ux.f; -#endif } diff --git a/system/lib/libc/musl/src/math/fabs.c b/system/lib/libc/musl/src/math/fabs.c index 566a461ffdd37..e8258cfdbcf1a 100644 --- a/system/lib/libc/musl/src/math/fabs.c +++ b/system/lib/libc/musl/src/math/fabs.c @@ -3,13 +3,7 @@ double fabs(double x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_fabs(x); -#else union {double f; uint64_t i;} u = {x}; u.i &= -1ULL/2; return u.f; -#endif } diff --git a/system/lib/libc/musl/src/math/fabsf.c b/system/lib/libc/musl/src/math/fabsf.c index 1ff074a720c75..4efc8d686dcc4 100644 --- a/system/lib/libc/musl/src/math/fabsf.c +++ b/system/lib/libc/musl/src/math/fabsf.c @@ -3,13 +3,7 @@ float fabsf(float x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_fabsf(x); -#else union {float f; uint32_t i;} u = {x}; u.i &= 0x7fffffff; return u.f; -#endif } diff --git a/system/lib/libc/musl/src/math/floor.c b/system/lib/libc/musl/src/math/floor.c index 179a9aca1de50..14a31cd8c4c54 100644 --- a/system/lib/libc/musl/src/math/floor.c +++ b/system/lib/libc/musl/src/math/floor.c @@ -1,21 +1,14 @@ #include "libm.h" -#ifndef __wasm__ #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON #endif static const double_t toint = 1/EPS; -#endif double floor(double x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_floor(x); -#else union {double f; uint64_t i;} u = {x}; int e = u.i >> 52 & 0x7ff; double_t y; @@ -35,5 +28,4 @@ double floor(double x) if (y > 0) return x + y - 1; return x + y; -#endif } diff --git a/system/lib/libc/musl/src/math/floorf.c b/system/lib/libc/musl/src/math/floorf.c index 4552d38bc5723..dceec739dbef5 100644 --- a/system/lib/libc/musl/src/math/floorf.c +++ b/system/lib/libc/musl/src/math/floorf.c @@ -2,11 +2,6 @@ float floorf(float x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_floorf(x); -#else union {float f; uint32_t i;} u = {x}; int e = (int)(u.i >> 23 & 0xff) - 0x7f; uint32_t m; @@ -29,5 +24,4 @@ float floorf(float x) u.f = -1.0; } return u.f; -#endif } diff --git a/system/lib/libc/musl/src/math/fma.c b/system/lib/libc/musl/src/math/fma.c index 5336a2d504467..0c6f90c9cfd14 100644 --- a/system/lib/libc/musl/src/math/fma.c +++ b/system/lib/libc/musl/src/math/fma.c @@ -41,9 +41,7 @@ static void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y) double fma(double x, double y, double z) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif /* normalize so top 10bits and last bit are 0 */ struct num nx, ny, nz; diff --git a/system/lib/libc/musl/src/math/fmaf.c b/system/lib/libc/musl/src/math/fmaf.c index bb4f6f1daa6eb..7c65acf1fc5e0 100644 --- a/system/lib/libc/musl/src/math/fmaf.c +++ b/system/lib/libc/musl/src/math/fmaf.c @@ -38,9 +38,7 @@ */ float fmaf(float x, float y, float z) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif double xy, result; union {double f; uint64_t i;} u; int e; diff --git a/system/lib/libc/musl/src/math/fmal.c b/system/lib/libc/musl/src/math/fmal.c index ac8ecbbb2a6e0..4506aac6f6abb 100644 --- a/system/lib/libc/musl/src/math/fmal.c +++ b/system/lib/libc/musl/src/math/fmal.c @@ -164,9 +164,7 @@ static inline struct dd dd_mul(long double a, long double b) */ long double fmal(long double x, long double y, long double z) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif long double xs, ys, zs, adj; struct dd xy, r; int oround; diff --git a/system/lib/libc/musl/src/math/fmax.c b/system/lib/libc/musl/src/math/fmax.c index 2018a78c6978a..94f0caa17751b 100644 --- a/system/lib/libc/musl/src/math/fmax.c +++ b/system/lib/libc/musl/src/math/fmax.c @@ -6,13 +6,8 @@ double fmax(double x, double y) return y; if (isnan(y)) return x; -// XXX EMSCRIPTEN: use wasm builtins for code size -#ifdef __wasm__ - return __builtin_wasm_max_f64(x, y); -#else /* handle signed zeros, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? y : x; return x < y ? y : x; -#endif } diff --git a/system/lib/libc/musl/src/math/fmaxf.c b/system/lib/libc/musl/src/math/fmaxf.c index 8524cee49dce3..695d8179c6c1c 100644 --- a/system/lib/libc/musl/src/math/fmaxf.c +++ b/system/lib/libc/musl/src/math/fmaxf.c @@ -6,13 +6,8 @@ float fmaxf(float x, float y) return y; if (isnan(y)) return x; -// XXX EMSCRIPTEN: use wasm builtins for code size -#ifdef __wasm__ - return __builtin_wasm_max_f32(x, y); -#else /* handle signed zeroes, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? y : x; return x < y ? y : x; -#endif } diff --git a/system/lib/libc/musl/src/math/fmin.c b/system/lib/libc/musl/src/math/fmin.c index 2334d7b898a30..08a8fd17f29e3 100644 --- a/system/lib/libc/musl/src/math/fmin.c +++ b/system/lib/libc/musl/src/math/fmin.c @@ -6,13 +6,8 @@ double fmin(double x, double y) return y; if (isnan(y)) return x; -// XXX EMSCRIPTEN: use wasm builtins for code size -#ifdef __wasm__ - return __builtin_wasm_min_f64(x, y); -#else /* handle signed zeros, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? x : y; return x < y ? x : y; -#endif } diff --git a/system/lib/libc/musl/src/math/fminf.c b/system/lib/libc/musl/src/math/fminf.c index bfbaafcef80b9..3573c7de741e1 100644 --- a/system/lib/libc/musl/src/math/fminf.c +++ b/system/lib/libc/musl/src/math/fminf.c @@ -6,13 +6,8 @@ float fminf(float x, float y) return y; if (isnan(y)) return x; -// XXX EMSCRIPTEN: use wasm builtins for code size -#ifdef __wasm__ - return __builtin_wasm_min_f32(x, y); -#else /* handle signed zeros, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? x : y; return x < y ? x : y; -#endif } diff --git a/system/lib/libc/musl/src/math/ilogb.c b/system/lib/libc/musl/src/math/ilogb.c index a52d78ef7dcec..64d40154d60ab 100644 --- a/system/lib/libc/musl/src/math/ilogb.c +++ b/system/lib/libc/musl/src/math/ilogb.c @@ -3,9 +3,7 @@ int ilogb(double x) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif union {double f; uint64_t i;} u = {x}; uint64_t i = u.i; int e = i>>52 & 0x7ff; diff --git a/system/lib/libc/musl/src/math/ilogbf.c b/system/lib/libc/musl/src/math/ilogbf.c index 18aef0ae043dd..e23ba209ec4cd 100644 --- a/system/lib/libc/musl/src/math/ilogbf.c +++ b/system/lib/libc/musl/src/math/ilogbf.c @@ -3,9 +3,7 @@ int ilogbf(float x) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif union {float f; uint32_t i;} u = {x}; uint32_t i = u.i; int e = i>>23 & 0xff; diff --git a/system/lib/libc/musl/src/math/ilogbl.c b/system/lib/libc/musl/src/math/ilogbl.c index 9931cac52ca6a..7b1a9cf8d007f 100644 --- a/system/lib/libc/musl/src/math/ilogbl.c +++ b/system/lib/libc/musl/src/math/ilogbl.c @@ -9,9 +9,7 @@ int ilogbl(long double x) #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 int ilogbl(long double x) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif union ldshape u = {x}; uint64_t m = u.i.m; int e = u.i.se & 0x7fff; @@ -34,9 +32,7 @@ int ilogbl(long double x) #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 int ilogbl(long double x) { -#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON -#endif union ldshape u = {x}; int e = u.i.se & 0x7fff; diff --git a/system/lib/libc/musl/src/math/log2_small.c b/system/lib/libc/musl/src/math/log2_small.c deleted file mode 100644 index 0aafad4b86c1c..0000000000000 --- a/system/lib/libc/musl/src/math/log2_small.c +++ /dev/null @@ -1,122 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log2.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* - * Return the base 2 logarithm of x. See log.c for most comments. - * - * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2 - * as in log.c, then combine and scale in extra precision: - * log2(x) = (f - f*f/2 + r)/log(2) + k - */ - -#include -#include - -static const double -ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ -ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */ -Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - -double log2(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo; - uint32_t hx; - int k; - - hx = u.i>>32; - k = 0; - if (hx < 0x00100000 || hx>>31) { - if (u.i<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (hx>>31) - return (x-x)/0.0; /* log(-#) = NaN */ - /* subnormal number, scale x up */ - k -= 54; - x *= 0x1p54; - u.f = x; - hx = u.i>>32; - } else if (hx >= 0x7ff00000) { - return x; - } else if (hx == 0x3ff00000 && u.i<<32 == 0) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - hx += 0x3ff00000 - 0x3fe6a09e; - k += (int)(hx>>20) - 0x3ff; - hx = (hx&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); - x = u.f; - - f = x - 1.0; - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - - /* - * f-hfsq must (for args near 1) be evaluated in extra precision - * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2). - * This is fairly efficient since f-hfsq only depends on f, so can - * be evaluated in parallel with R. Not combining hfsq with R also - * keeps R small (though not as small as a true `lo' term would be), - * so that extra precision is not needed for terms involving R. - * - * Compiler bugs involving extra precision used to break Dekker's - * theorem for spitting f-hfsq as hi+lo, unless double_t was used - * or the multi-precision calculations were avoided when double_t - * has extra precision. These problems are now automatically - * avoided as a side effect of the optimization of combining the - * Dekker splitting step with the clear-low-bits step. - * - * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra - * precision to avoid a very large cancellation when x is very near - * these values. Unlike the above cancellations, this problem is - * specific to base 2. It is strange that adding +-1 is so much - * harder than adding +-ln2 or +-log10_2. - * - * This uses Dekker's theorem to normalize y+val_hi, so the - * compiler bugs are back in some configurations, sigh. And I - * don't want to used double_t to avoid them, since that gives a - * pessimization and the support for avoiding the pessimization - * is not yet available. - * - * The multi-precision calculations for the multiplications are - * routine. - */ - - /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ - hi = f - hfsq; - u.f = hi; - u.i &= (uint64_t)-1<<32; - hi = u.f; - lo = f - hi - hfsq + s*(hfsq+R); - - val_hi = hi*ivln2hi; - val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; - - /* spadd(val_hi, val_lo, y), except for not using double_t: */ - y = k; - w = y + val_hi; - val_lo += (y - w) + val_hi; - val_hi = w; - - return val_lo + val_hi; -} diff --git a/system/lib/libc/musl/src/math/log_small.c b/system/lib/libc/musl/src/math/log_small.c deleted file mode 100644 index e61e113d41af9..0000000000000 --- a/system/lib/libc/musl/src/math/log_small.c +++ /dev/null @@ -1,118 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* log(x) - * Return the logarithm of x - * - * Method : - * 1. Argument Reduction: find k and f such that - * x = 2^k * (1+f), - * where sqrt(2)/2 < 1+f < sqrt(2) . - * - * 2. Approximation of log(1+f). - * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) - * = 2s + 2/3 s**3 + 2/5 s**5 + ....., - * = 2s + s*R - * We use a special Remez algorithm on [0,0.1716] to generate - * a polynomial of degree 14 to approximate R The maximum error - * of this polynomial approximation is bounded by 2**-58.45. In - * other words, - * 2 4 6 8 10 12 14 - * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s - * (the values of Lg1 to Lg7 are listed in the program) - * and - * | 2 14 | -58.45 - * | Lg1*s +...+Lg7*s - R(z) | <= 2 - * | | - * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. - * In order to guarantee error in log below 1ulp, we compute log - * by - * log(1+f) = f - s*(f - R) (if f is not too large) - * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) - * - * 3. Finally, log(x) = k*ln2 + log(1+f). - * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) - * Here ln2 is split into two floating point number: - * ln2_hi + ln2_lo, - * where n*ln2_hi is always exact for |n| < 2000. - * - * Special cases: - * log(x) is NaN with signal if x < 0 (including -INF) ; - * log(+INF) is +INF; log(0) is -INF with signal; - * log(NaN) is that NaN with no signal. - * - * Accuracy: - * according to an error analysis, the error is always less than - * 1 ulp (unit in the last place). - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include -#include - -static const double -ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ -ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ -Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - -double log(double x) -{ - union {double f; uint64_t i;} u = {x}; - double_t hfsq,f,s,z,R,w,t1,t2,dk; - uint32_t hx; - int k; - - hx = u.i>>32; - k = 0; - if (hx < 0x00100000 || hx>>31) { - if (u.i<<1 == 0) - return -1/(x*x); /* log(+-0)=-inf */ - if (hx>>31) - return (x-x)/0.0; /* log(-#) = NaN */ - /* subnormal number, scale x up */ - k -= 54; - x *= 0x1p54; - u.f = x; - hx = u.i>>32; - } else if (hx >= 0x7ff00000) { - return x; - } else if (hx == 0x3ff00000 && u.i<<32 == 0) - return 0; - - /* reduce x into [sqrt(2)/2, sqrt(2)] */ - hx += 0x3ff00000 - 0x3fe6a09e; - k += (int)(hx>>20) - 0x3ff; - hx = (hx&0x000fffff) + 0x3fe6a09e; - u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); - x = u.f; - - f = x - 1.0; - hfsq = 0.5*f*f; - s = f/(2.0+f); - z = s*s; - w = z*z; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - R = t2 + t1; - dk = k; - return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; -} diff --git a/system/lib/libc/musl/src/math/pow_small.c b/system/lib/libc/musl/src/math/pow_small.c deleted file mode 100644 index b66f632d8eea9..0000000000000 --- a/system/lib/libc/musl/src/math/pow_small.c +++ /dev/null @@ -1,328 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */ -/* - * ==================================================== - * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. - * - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ -/* pow(x,y) return x**y - * - * n - * Method: Let x = 2 * (1+f) - * 1. Compute and return log2(x) in two pieces: - * log2(x) = w1 + w2, - * where w1 has 53-24 = 29 bit trailing zeros. - * 2. Perform y*log2(x) = n+y' by simulating muti-precision - * arithmetic, where |y'|<=0.5. - * 3. Return x**y = 2**n*exp(y'*log2) - * - * Special cases: - * 1. (anything) ** 0 is 1 - * 2. 1 ** (anything) is 1 - * 3. (anything except 1) ** NAN is NAN - * 4. NAN ** (anything except 0) is NAN - * 5. +-(|x| > 1) ** +INF is +INF - * 6. +-(|x| > 1) ** -INF is +0 - * 7. +-(|x| < 1) ** +INF is +0 - * 8. +-(|x| < 1) ** -INF is +INF - * 9. -1 ** +-INF is 1 - * 10. +0 ** (+anything except 0, NAN) is +0 - * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 - * 12. +0 ** (-anything except 0, NAN) is +INF, raise divbyzero - * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF, raise divbyzero - * 14. -0 ** (+odd integer) is -0 - * 15. -0 ** (-odd integer) is -INF, raise divbyzero - * 16. +INF ** (+anything except 0,NAN) is +INF - * 17. +INF ** (-anything except 0,NAN) is +0 - * 18. -INF ** (+odd integer) is -INF - * 19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer) - * 20. (anything) ** 1 is (anything) - * 21. (anything) ** -1 is 1/(anything) - * 22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) - * 23. (-anything except 0 and inf) ** (non-integer) is NAN - * - * Accuracy: - * pow(x,y) returns x**y nearly rounded. In particular - * pow(integer,integer) - * always returns the correct integer provided it is - * representable. - * - * Constants : - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "libm.h" - -static const double -bp[] = {1.0, 1.5,}, -dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ -dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ -two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ -huge = 1.0e300, -tiny = 1.0e-300, -/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ -L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ -L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ -L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ -L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ -L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ -P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ -P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ -P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ -P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ -P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ -lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ -lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ -lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ -ovt = 8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */ -cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ -cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ -cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ -ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ -ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ -ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ - -double pow(double x, double y) -{ - double z,ax,z_h,z_l,p_h,p_l; - double y1,t1,t2,r,s,t,u,v,w; - int32_t i,j,k,yisint,n; - int32_t hx,hy,ix,iy; - uint32_t lx,ly; - - EXTRACT_WORDS(hx, lx, x); - EXTRACT_WORDS(hy, ly, y); - ix = hx & 0x7fffffff; - iy = hy & 0x7fffffff; - - /* x**0 = 1, even if x is NaN */ - if ((iy|ly) == 0) - return 1.0; - /* 1**y = 1, even if y is NaN */ - if (hx == 0x3ff00000 && lx == 0) - return 1.0; - /* NaN if either arg is NaN */ - if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) || - iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 0)) - return x + y; - - /* determine if y is an odd int when x < 0 - * yisint = 0 ... y is not an integer - * yisint = 1 ... y is an odd int - * yisint = 2 ... y is an even int - */ - yisint = 0; - if (hx < 0) { - if (iy >= 0x43400000) - yisint = 2; /* even integer y */ - else if (iy >= 0x3ff00000) { - k = (iy>>20) - 0x3ff; /* exponent */ - if (k > 20) { - j = ly>>(52-k); - if ((j<<(52-k)) == ly) - yisint = 2 - (j&1); - } else if (ly == 0) { - j = iy>>(20-k); - if ((j<<(20-k)) == iy) - yisint = 2 - (j&1); - } - } - } - - /* special value of y */ - if (ly == 0) { - if (iy == 0x7ff00000) { /* y is +-inf */ - if (((ix-0x3ff00000)|lx) == 0) /* (-1)**+-inf is 1 */ - return 1.0; - else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ - return hy >= 0 ? y : 0.0; - else /* (|x|<1)**+-inf = 0,inf */ - return hy >= 0 ? 0.0 : -y; - } - if (iy == 0x3ff00000) { /* y is +-1 */ - if (hy >= 0) - return x; - y = 1/x; -#if FLT_EVAL_METHOD!=0 - { - union {double f; uint64_t i;} u = {y}; - uint64_t i = u.i & -1ULL/2; - if (i>>52 == 0 && (i&(i-1))) - FORCE_EVAL((float)y); - } -#endif - return y; - } - if (hy == 0x40000000) /* y is 2 */ - return x*x; - if (hy == 0x3fe00000) { /* y is 0.5 */ - if (hx >= 0) /* x >= +0 */ - return sqrt(x); - } - } - - ax = fabs(x); - /* special value of x */ - if (lx == 0) { - if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */ - z = ax; - if (hy < 0) /* z = (1/|x|) */ - z = 1.0/z; - if (hx < 0) { - if (((ix-0x3ff00000)|yisint) == 0) { - z = (z-z)/(z-z); /* (-1)**non-int is NaN */ - } else if (yisint == 1) - z = -z; /* (x<0)**odd = -(|x|**odd) */ - } - return z; - } - } - - s = 1.0; /* sign of result */ - if (hx < 0) { - if (yisint == 0) /* (x<0)**(non-int) is NaN */ - return (x-x)/(x-x); - if (yisint == 1) /* (x<0)**(odd int) */ - s = -1.0; - } - - /* |y| is huge */ - if (iy > 0x41e00000) { /* if |y| > 2**31 */ - if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ - if (ix <= 0x3fefffff) - return hy < 0 ? huge*huge : tiny*tiny; - if (ix >= 0x3ff00000) - return hy > 0 ? huge*huge : tiny*tiny; - } - /* over/underflow if x is not close to one */ - if (ix < 0x3fefffff) - return hy < 0 ? s*huge*huge : s*tiny*tiny; - if (ix > 0x3ff00000) - return hy > 0 ? s*huge*huge : s*tiny*tiny; - /* now |1-x| is tiny <= 2**-20, suffice to compute - log(x) by x-x^2/2+x^3/3-x^4/4 */ - t = ax - 1.0; /* t has 20 trailing zeros */ - w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25)); - u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ - v = t*ivln2_l - w*ivln2; - t1 = u + v; - SET_LOW_WORD(t1, 0); - t2 = v - (t1-u); - } else { - double ss,s2,s_h,s_l,t_h,t_l; - n = 0; - /* take care subnormal number */ - if (ix < 0x00100000) { - ax *= two53; - n -= 53; - GET_HIGH_WORD(ix,ax); - } - n += ((ix)>>20) - 0x3ff; - j = ix & 0x000fffff; - /* determine interval */ - ix = j | 0x3ff00000; /* normalize ix */ - if (j <= 0x3988E) /* |x|>1)|0x20000000) + 0x00080000 + (k<<18)); - t_l = ax - (t_h-bp[k]); - s_l = v*((u-s_h*t_h)-s_h*t_l); - /* compute log(ax) */ - s2 = ss*ss; - r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); - r += s_l*(s_h+ss); - s2 = s_h*s_h; - t_h = 3.0 + s2 + r; - SET_LOW_WORD(t_h, 0); - t_l = r - ((t_h-3.0)-s2); - /* u+v = ss*(1+...) */ - u = s_h*t_h; - v = s_l*t_h + t_l*ss; - /* 2/(3log2)*(ss+...) */ - p_h = u + v; - SET_LOW_WORD(p_h, 0); - p_l = v - (p_h-u); - z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ - z_l = cp_l*p_h+p_l*cp + dp_l[k]; - /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (double)n; - t1 = ((z_h + z_l) + dp_h[k]) + t; - SET_LOW_WORD(t1, 0); - t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); - } - - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - y1 = y; - SET_LOW_WORD(y1, 0); - p_l = (y-y1)*t1 + y*t2; - p_h = y1*t1; - z = p_l + p_h; - EXTRACT_WORDS(j, i, z); - if (j >= 0x40900000) { /* z >= 1024 */ - if (((j-0x40900000)|i) != 0) /* if z > 1024 */ - return s*huge*huge; /* overflow */ - if (p_l + ovt > z - p_h) - return s*huge*huge; /* overflow */ - } else if ((j&0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ // FIXME: instead of abs(j) use unsigned j - if (((j-0xc090cc00)|i) != 0) /* z < -1075 */ - return s*tiny*tiny; /* underflow */ - if (p_l <= z - p_h) - return s*tiny*tiny; /* underflow */ - } - /* - * compute 2**(p_h+p_l) - */ - i = j & 0x7fffffff; - k = (i>>20) - 0x3ff; - n = 0; - if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ - n = j + (0x00100000>>(k+1)); - k = ((n&0x7fffffff)>>20) - 0x3ff; /* new k for n */ - t = 0.0; - SET_HIGH_WORD(t, n & ~(0x000fffff>>k)); - n = ((n&0x000fffff)|0x00100000)>>(20-k); - if (j < 0) - n = -n; - p_h -= t; - } - t = p_l + p_h; - SET_LOW_WORD(t, 0); - u = t*lg2_h; - v = (p_l-(t-p_h))*lg2 + t*lg2_l; - z = u + v; - w = v - (z-u); - t = z*z; - t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - r = (z*t1)/(t1-2.0) - (w + z*w); - z = 1.0 - (r-z); - GET_HIGH_WORD(j, z); - j += n<<20; - if ((j>>20) <= 0) /* subnormal output */ - z = scalbn(z,n); - else - SET_HIGH_WORD(z, j); - return s*z; -} diff --git a/system/lib/libc/musl/src/math/rint.c b/system/lib/libc/musl/src/math/rint.c index bd4c32f9f6d77..fbba390e7d723 100644 --- a/system/lib/libc/musl/src/math/rint.c +++ b/system/lib/libc/musl/src/math/rint.c @@ -2,22 +2,15 @@ #include #include -#ifndef __wasm__ #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON #endif static const double_t toint = 1/EPS; -#endif double rint(double x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_rint(x); -#else union {double f; uint64_t i;} u = {x}; int e = u.i>>52 & 0x7ff; int s = u.i>>63; @@ -32,5 +25,4 @@ double rint(double x) if (y == 0) return s ? -0.0 : 0; return y; -#endif } diff --git a/system/lib/libc/musl/src/math/rintf.c b/system/lib/libc/musl/src/math/rintf.c index 59401f2bf75cb..9047688d246a6 100644 --- a/system/lib/libc/musl/src/math/rintf.c +++ b/system/lib/libc/musl/src/math/rintf.c @@ -2,7 +2,6 @@ #include #include -#ifndef __wasm__ #if FLT_EVAL_METHOD==0 #define EPS FLT_EPSILON #elif FLT_EVAL_METHOD==1 @@ -11,15 +10,9 @@ #define EPS LDBL_EPSILON #endif static const float_t toint = 1/EPS; -#endif float rintf(float x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_rintf(x); -#else union {float f; uint32_t i;} u = {x}; int e = u.i>>23 & 0xff; int s = u.i>>31; @@ -34,5 +27,4 @@ float rintf(float x) if (y == 0) return s ? -0.0f : 0.0f; return y; -#endif } diff --git a/system/lib/libc/musl/src/math/sqrt.c b/system/lib/libc/musl/src/math/sqrt.c index 6854c98381642..5ba2655962135 100644 --- a/system/lib/libc/musl/src/math/sqrt.c +++ b/system/lib/libc/musl/src/math/sqrt.c @@ -5,7 +5,6 @@ #define FENV_SUPPORT 1 -#ifndef __wasm__ /* returns a*b*2^-32 - e, with error 0 <= e < 1. */ static inline uint32_t mul32(uint32_t a, uint32_t b) { @@ -21,15 +20,9 @@ static inline uint64_t mul64(uint64_t a, uint64_t b) uint64_t blo = b&0xffffffff; return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32); } -#endif double sqrt(double x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_sqrt(x); -#else uint64_t ix, top, m; /* special case handling. */ @@ -162,5 +155,4 @@ double sqrt(double x) y = eval_as_double(y + t); } return y; -#endif } diff --git a/system/lib/libc/musl/src/math/sqrtf.c b/system/lib/libc/musl/src/math/sqrtf.c index fd74702691215..740d81cbab421 100644 --- a/system/lib/libc/musl/src/math/sqrtf.c +++ b/system/lib/libc/musl/src/math/sqrtf.c @@ -3,24 +3,17 @@ #include "libm.h" #include "sqrt_data.h" -#ifndef __wasm__ #define FENV_SUPPORT 1 static inline uint32_t mul32(uint32_t a, uint32_t b) { return (uint64_t)a*b >> 32; } -#endif /* see sqrt.c for more detailed comments. */ float sqrtf(float x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_sqrtf(x); -#else uint32_t ix, m, m1, m0, even, ey; ix = asuint(x); @@ -87,5 +80,4 @@ float sqrtf(float x) y = eval_as_float(y + t); } return y; -#endif } diff --git a/system/lib/libc/musl/src/math/sqrtl.c b/system/lib/libc/musl/src/math/sqrtl.c index 81e68fea20c39..a231b3f2016b3 100644 --- a/system/lib/libc/musl/src/math/sqrtl.c +++ b/system/lib/libc/musl/src/math/sqrtl.c @@ -176,10 +176,6 @@ static inline u128 mul128_tail(u128 a, u128 b) /* see sqrt.c for detailed comments. */ -#ifdef __EMSCRIPTEN__ -// https://github.com/emscripten-core/emscripten/issues/15655 -__attribute__((no_sanitize("address"))) -#endif long double sqrtl(long double x) { u128 ix, ml; diff --git a/system/lib/libc/musl/src/math/trunc.c b/system/lib/libc/musl/src/math/trunc.c index c6d25ec1b456e..d13711b5015e0 100644 --- a/system/lib/libc/musl/src/math/trunc.c +++ b/system/lib/libc/musl/src/math/trunc.c @@ -2,11 +2,6 @@ double trunc(double x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_trunc(x); -#else union {double f; uint64_t i;} u = {x}; int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12; uint64_t m; @@ -21,5 +16,4 @@ double trunc(double x) FORCE_EVAL(x + 0x1p120f); u.i &= ~m; return u.f; -#endif } diff --git a/system/lib/libc/musl/src/math/truncf.c b/system/lib/libc/musl/src/math/truncf.c index 3c9f7f4661736..1a7d03c3bce10 100644 --- a/system/lib/libc/musl/src/math/truncf.c +++ b/system/lib/libc/musl/src/math/truncf.c @@ -2,11 +2,6 @@ float truncf(float x) { -// XXX EMSCRIPTEN: use the wasm instruction via clang builtin -// See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ - return __builtin_truncf(x); -#else union {float f; uint32_t i;} u = {x}; int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9; uint32_t m; @@ -21,5 +16,4 @@ float truncf(float x) FORCE_EVAL(x + 0x1p120f); u.i &= ~m; return u.f; -#endif } diff --git a/system/lib/libc/musl/src/misc/getentropy.c b/system/lib/libc/musl/src/misc/getentropy.c index c42689f427530..651ea95f14310 100644 --- a/system/lib/libc/musl/src/misc/getentropy.c +++ b/system/lib/libc/musl/src/misc/getentropy.c @@ -4,10 +4,6 @@ #include #include -#ifdef __EMSCRIPTEN__ -#include -#endif - int getentropy(void *buffer, size_t len) { int cs, ret = 0; @@ -18,9 +14,6 @@ int getentropy(void *buffer, size_t len) return -1; } -#ifdef __EMSCRIPTEN__ - ret = __wasi_syscall_ret(__wasi_random_get(buffer, len)); -#else pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); while (len) { @@ -35,7 +28,6 @@ int getentropy(void *buffer, size_t len) } pthread_setcancelstate(cs, 0); -#endif return ret; } diff --git a/system/lib/libc/musl/src/misc/getopt.c b/system/lib/libc/musl/src/misc/getopt.c index b08abbc96871b..b02b81c34329b 100644 --- a/system/lib/libc/musl/src/misc/getopt.c +++ b/system/lib/libc/musl/src/misc/getopt.c @@ -16,7 +16,7 @@ weak_alias(__optreset, optreset); void __getopt_msg(const char *a, const char *b, const char *c, size_t l) { FILE *f = stderr; - b = LCTRANS_CUR(b); /* XXX EMSCRIPTEN: Use macro version here */ + b = __lctrans_cur(b); FLOCK(f); fputs(a, f)>=0 && fwrite(b, strlen(b), 1, f) diff --git a/system/lib/libc/musl/src/misc/ioctl.c b/system/lib/libc/musl/src/misc/ioctl.c index 0dd521ad58dfe..35804f026ef68 100644 --- a/system/lib/libc/musl/src/misc/ioctl.c +++ b/system/lib/libc/musl/src/misc/ioctl.c @@ -9,12 +9,7 @@ #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ -// The upstream version below is UB in C2x and rejected by clang. -#define alignof(t) _Alignof(t) -#else #define alignof(t) offsetof(struct { char c; t x; }, x) -#endif #define W 1 #define R 2 diff --git a/system/lib/libc/musl/src/mman/mmap.c b/system/lib/libc/musl/src/mman/mmap.c index c755ca849eff4..43e5e02941dc7 100644 --- a/system/lib/libc/musl/src/mman/mmap.c +++ b/system/lib/libc/musl/src/mman/mmap.c @@ -37,4 +37,3 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off) } weak_alias(__mmap, mmap); -weak_alias(__mmap, emscripten_builtin_mmap); diff --git a/system/lib/libc/musl/src/mman/munmap.c b/system/lib/libc/musl/src/mman/munmap.c index 083e77285ee3a..2bf83bbe9b702 100644 --- a/system/lib/libc/musl/src/mman/munmap.c +++ b/system/lib/libc/musl/src/mman/munmap.c @@ -11,4 +11,3 @@ int __munmap(void *start, size_t len) } weak_alias(__munmap, munmap); -weak_alias(__munmap, emscripten_builtin_munmap); diff --git a/system/lib/libc/musl/src/multibyte/mbsrtowcs.c b/system/lib/libc/musl/src/multibyte/mbsrtowcs.c index 32d74154f84d1..9b2f2dfbb023b 100644 --- a/system/lib/libc/musl/src/multibyte/mbsrtowcs.c +++ b/system/lib/libc/musl/src/multibyte/mbsrtowcs.c @@ -38,8 +38,7 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs } if (!ws) for (;;) { -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ typedef uint32_t __attribute__((__may_alias__)) w32; if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { while (!(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) { @@ -73,8 +72,7 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs *src = (const void *)s; return wn0; } -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ typedef uint32_t __attribute__((__may_alias__)) w32; if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { while (wn>=5 && !(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) { diff --git a/system/lib/libc/musl/src/network/freeaddrinfo.c b/system/lib/libc/musl/src/network/freeaddrinfo.c index c4016d9f7c246..62241c239e27f 100644 --- a/system/lib/libc/musl/src/network/freeaddrinfo.c +++ b/system/lib/libc/musl/src/network/freeaddrinfo.c @@ -6,13 +6,6 @@ void freeaddrinfo(struct addrinfo *p) { -#if __EMSCRIPTEN__ - // Emscripten's usage of this structure is very simple: we always allocate - // ai_addr, and do not use the linked list aspect at all. There is also no - // aliasing with aibuf. - free(p->ai_addr); - free(p); -#else size_t cnt; for (cnt=1; p->ai_next; cnt++, p=p->ai_next); struct aibuf *b = (void *)((char *)p - offsetof(struct aibuf, ai)); @@ -20,5 +13,4 @@ void freeaddrinfo(struct addrinfo *p) LOCK(b->lock); if (!(b->ref -= cnt)) free(b); else UNLOCK(b->lock); -#endif } diff --git a/system/lib/libc/musl/src/network/if_indextoname.c b/system/lib/libc/musl/src/network/if_indextoname.c index 830e1a2dac159..3b368bf0d1329 100644 --- a/system/lib/libc/musl/src/network/if_indextoname.c +++ b/system/lib/libc/musl/src/network/if_indextoname.c @@ -14,11 +14,7 @@ char *if_indextoname(unsigned index, char *name) if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0; ifr.ifr_ifindex = index; r = ioctl(fd, SIOCGIFNAME, &ifr); -#ifdef __EMSCRIPTEN__ - __wasi_fd_close(fd); -#else __syscall(SYS_close, fd); -#endif if (r < 0) { if (errno == ENODEV) errno = ENXIO; return 0; diff --git a/system/lib/libc/musl/src/network/if_nametoindex.c b/system/lib/libc/musl/src/network/if_nametoindex.c index 5d61e579b3b61..331413c68912d 100644 --- a/system/lib/libc/musl/src/network/if_nametoindex.c +++ b/system/lib/libc/musl/src/network/if_nametoindex.c @@ -13,10 +13,6 @@ unsigned if_nametoindex(const char *name) if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0; strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); r = ioctl(fd, SIOCGIFINDEX, &ifr); -#ifdef __EMSCRIPTEN__ - __wasi_fd_close(fd); -#else __syscall(SYS_close, fd); -#endif return r < 0 ? 0 : ifr.ifr_ifindex; } diff --git a/system/lib/libc/musl/src/network/netlink.c b/system/lib/libc/musl/src/network/netlink.c index 676b65cde3972..94dba7f5c9e40 100644 --- a/system/lib/libc/musl/src/network/netlink.c +++ b/system/lib/libc/musl/src/network/netlink.c @@ -47,10 +47,6 @@ int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct if (fd < 0) return -1; r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx); if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx); -#ifdef __EMSCRIPTEN__ - __wasi_fd_close(fd); -#else __syscall(SYS_close,fd); -#endif return r; } diff --git a/system/lib/libc/musl/src/network/ns_parse.c b/system/lib/libc/musl/src/network/ns_parse.c index 71bd309cfdc7f..d01da47a3d411 100644 --- a/system/lib/libc/musl/src/network/ns_parse.c +++ b/system/lib/libc/musl/src/network/ns_parse.c @@ -47,30 +47,6 @@ void ns_put32(unsigned long l, unsigned char *cp) *cp++ = l; } -int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count) -{ - const unsigned char *p = ptr; - int r; - - while (count--) { - r = dn_skipname(p, eom); - if (r < 0) goto bad; - if (r + 2 * NS_INT16SZ > eom - p) goto bad; - p += r + 2 * NS_INT16SZ; - if (section != ns_s_qd) { - if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad; - p += NS_INT32SZ; - NS_GET16(r, p); - if (r > eom - p) goto bad; - p += r; - } - } - return p - ptr; -bad: - errno = EMSGSIZE; - return -1; -} - int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle) { int i, r; @@ -101,20 +77,35 @@ int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle) return -1; } -int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom, - const unsigned char *src, char *dst, size_t dstsiz) +int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count) { + const unsigned char *p = ptr; int r; - r = dn_expand(msg, eom, src, dst, dstsiz); - if (r < 0) errno = EMSGSIZE; - return r; + + while (count--) { + r = dn_skipname(p, eom); + if (r < 0) goto bad; + if (r + 2 * NS_INT16SZ > eom - p) goto bad; + p += r + 2 * NS_INT16SZ; + if (section != ns_s_qd) { + if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad; + p += NS_INT32SZ; + NS_GET16(r, p); + if (r > eom - p) goto bad; + p += r; + } + } + return p - ptr; +bad: + errno = EMSGSIZE; + return -1; } int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { int r; - if (section >= ns_s_max) goto bad; + if (section < 0 || section >= ns_s_max) goto bad; if (section != handle->_sect) { handle->_sect = section; handle->_rrnum = 0; @@ -169,3 +160,12 @@ int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) return -1; } +int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom, + const unsigned char *src, char *dst, size_t dstsiz) +{ + int r; + r = dn_expand(msg, eom, src, dst, dstsiz); + if (r < 0) errno = EMSGSIZE; + return r; +} + diff --git a/system/lib/libc/musl/src/network/recvmmsg.c b/system/lib/libc/musl/src/network/recvmmsg.c index 7ef9ad1894ec6..2978e2f64f34e 100644 --- a/system/lib/libc/musl/src/network/recvmmsg.c +++ b/system/lib/libc/musl/src/network/recvmmsg.c @@ -12,7 +12,7 @@ hidden void __convert_scm_timestamps(struct msghdr *, socklen_t); int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec *timeout) { -#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) +#if LONG_MAX > INT_MAX struct mmsghdr *mh = msgvec; unsigned int i; for (i = vlen; i; i--, mh++) diff --git a/system/lib/libc/musl/src/network/recvmsg.c b/system/lib/libc/musl/src/network/recvmsg.c index a973763a85a2e..03641625e8af7 100644 --- a/system/lib/libc/musl/src/network/recvmsg.c +++ b/system/lib/libc/musl/src/network/recvmsg.c @@ -51,7 +51,7 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) { ssize_t r; socklen_t orig_controllen = msg->msg_controllen; -#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) +#if LONG_MAX > INT_MAX struct msghdr h, *orig = msg; if (msg) { h = *msg; @@ -61,7 +61,7 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) #endif r = socketcall_cp(recvmsg, fd, msg, flags, 0, 0, 0); if (r >= 0) __convert_scm_timestamps(msg, orig_controllen); -#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) +#if LONG_MAX > INT_MAX if (orig) *orig = h; #endif return r; diff --git a/system/lib/libc/musl/src/network/res_msend.c b/system/lib/libc/musl/src/network/res_msend.c index 109942806c29e..86c2fcf4ff210 100644 --- a/system/lib/libc/musl/src/network/res_msend.c +++ b/system/lib/libc/musl/src/network/res_msend.c @@ -19,11 +19,7 @@ static void cleanup(void *p) { struct pollfd *pfd = p; for (int i=0; pfd[i].fd >= -1; i++) -#ifdef __EMSCRIPTEN__ - if (pfd[i].fd >= 0) __wasi_fd_close((intptr_t)pfd[i].fd); -#else if (pfd[i].fd >= 0) __syscall(SYS_close, pfd[i].fd); -#endif } static unsigned long mtime() @@ -307,11 +303,7 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries, * Immediately close TCP socket so as not to consume * resources we no longer need. */ alens[i] = alen; -#ifdef __EMSCRIPTEN__ - __wasi_fd_close((intptr_t)pfd[i].fd); -#else __syscall(SYS_close, pfd[i].fd); -#endif pfd[i].fd = -1; } } diff --git a/system/lib/libc/musl/src/network/sendmsg.c b/system/lib/libc/musl/src/network/sendmsg.c index fbdc00e07377f..acdfdf29247f0 100644 --- a/system/lib/libc/musl/src/network/sendmsg.c +++ b/system/lib/libc/musl/src/network/sendmsg.c @@ -6,7 +6,7 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) { -#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) +#if LONG_MAX > INT_MAX struct msghdr h; /* Kernels before 2.6.38 set SCM_MAX_FD to 255, allocate enough * space to support an SCM_RIGHTS ancillary message with 255 fds. diff --git a/system/lib/libc/musl/src/process/fexecve.c b/system/lib/libc/musl/src/process/fexecve.c index 37fb294482093..554c1981b670f 100644 --- a/system/lib/libc/musl/src/process/fexecve.c +++ b/system/lib/libc/musl/src/process/fexecve.c @@ -6,10 +6,8 @@ int fexecve(int fd, char *const argv[], char *const envp[]) { -#ifndef __EMSCRIPTEN__ int r = __syscall(SYS_execveat, fd, "", argv, envp, AT_EMPTY_PATH); if (r != -ENOSYS) return __syscall_ret(r); -#endif char buf[15 + 3*sizeof(int)]; __procfdname(buf, fd); execve(buf, argv, envp); diff --git a/system/lib/libc/musl/src/sched/sched_yield.c b/system/lib/libc/musl/src/sched/sched_yield.c index 7bd3846fc239e..ee6f0e7f16041 100644 --- a/system/lib/libc/musl/src/sched/sched_yield.c +++ b/system/lib/libc/musl/src/sched/sched_yield.c @@ -1,21 +1,7 @@ #include #include "syscall.h" -#if __EMSCRIPTEN__ -#include -#include -#include "threading_internal.h" -#endif - int sched_yield() { -#if __EMSCRIPTEN__ - // SharedArrayBuffer and wasm threads do not support explicit yielding. - // For now we at least call `emscripten_yield` which processes the event queue - // (along with other essential tasks). - _emscripten_yield(emscripten_get_now()); - return 0; -#else return syscall(SYS_sched_yield); -#endif } diff --git a/system/lib/libc/musl/src/select/ppoll.c b/system/lib/libc/musl/src/select/ppoll.c index 3b2d51133d415..9a0bf929584d7 100644 --- a/system/lib/libc/musl/src/select/ppoll.c +++ b/system/lib/libc/musl/src/select/ppoll.c @@ -9,16 +9,6 @@ int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_t *mask) { -#ifdef __EMSCRIPTEN__ - // Emscripten does not support true async signals so we just implement ppoll - // in terms of poll here in userspace. - int timeout = (to == NULL) ? -1 : (to->tv_sec * 1000 + to->tv_nsec / 1000000); - sigset_t origmask; - if (mask) pthread_sigmask(SIG_SETMASK, mask, &origmask); - int rtn = poll(fds, n, timeout); - if (mask) pthread_sigmask(SIG_SETMASK, &origmask, NULL); - return rtn; -#else time_t s = to ? to->tv_sec : 0; long ns = to ? to->tv_nsec : 0; #ifdef SYS_ppoll_time64 @@ -33,5 +23,4 @@ int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_ #endif return syscall_cp(SYS_ppoll, fds, n, to ? ((long[]){s, ns}) : 0, mask, _NSIG/8); -#endif } diff --git a/system/lib/libc/musl/src/select/pselect.c b/system/lib/libc/musl/src/select/pselect.c index 519a770b80657..54cfb291bba2c 100644 --- a/system/lib/libc/musl/src/select/pselect.c +++ b/system/lib/libc/musl/src/select/pselect.c @@ -9,20 +9,6 @@ int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec *restrict ts, const sigset_t *restrict mask) { -#ifdef __EMSCRIPTEN__ - // Emscripten does not support true async signals so we just implement pselect - // in terms of select here in userspace. - struct timeval tv_timeout; - if (ts) { - tv_timeout.tv_sec = ts->tv_sec; - tv_timeout.tv_usec = ts->tv_nsec / 1000; - } - sigset_t origmask; - if (mask) pthread_sigmask(SIG_SETMASK, mask, &origmask); - int rtn = select(n, rfds, wfds, efds, ts ? &tv_timeout : NULL); - if (mask) pthread_sigmask(SIG_SETMASK, &origmask, NULL); - return rtn; -#else syscall_arg_t data[2] = { (uintptr_t)mask, _NSIG/8 }; time_t s = ts ? ts->tv_sec : 0; long ns = ts ? ts->tv_nsec : 0; @@ -37,5 +23,4 @@ int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restric #endif return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, ts ? ((long[]){s, ns}) : 0, data); -#endif } diff --git a/system/lib/libc/musl/src/select/select.c b/system/lib/libc/musl/src/select/select.c index 8b5b533359761..f1d72863c6759 100644 --- a/system/lib/libc/musl/src/select/select.c +++ b/system/lib/libc/musl/src/select/select.c @@ -7,12 +7,6 @@ #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) -#ifdef __EMSCRIPTEN__ -#include -#include -static int emscripten_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv); -#endif - int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv) { time_t s = tv ? tv->tv_sec : 0; @@ -21,9 +15,6 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1; if (s<0 || us<0) return __syscall_ret(-EINVAL); -#ifdef __EMSCRIPTEN__ - return emscripten_select(n, rfds, wfds, efds, tv); -#else if (us/1000000 > max_time - s) { s = max_time; us = 999999; @@ -33,6 +24,7 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict us %= 1000000; ns = us*1000; } + #ifdef SYS_pselect6_time64 int r = -ENOSYS; if (SYS_pselect6 == SYS_pselect6_time64 || !IS32BIT(s)) @@ -50,79 +42,4 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? ((long[]){s, ns}) : 0, ((syscall_arg_t[]){ 0, _NSIG/8 })); #endif -#endif } - -#ifdef __EMSCRIPTEN__ -static int emscripten_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv) -{ - // Implement select in terms of `poll()` - - // Part 1: convert select arguments into poll arguments - - time_t s = tv ? tv->tv_sec : 0; - suseconds_t us = tv ? tv->tv_usec : 0; - int timeout = tv ? s * 1000 + (us / 1000) : -1; - int n = 0; - struct pollfd* fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd)); - - for (int i = 0; i < nfds; i++) { - if (readfds && FD_ISSET(i, readfds)) { - fds[n].events |= POLLIN; - } - if (writefds && FD_ISSET(i, writefds)) { - fds[n].events |= POLLOUT; - } - if (exceptfds && FD_ISSET(i, exceptfds)) { - fds[n].events |= POLLPRI; - } - if (fds[n].events) { - fds[n].fd = i; - n++; - } - } - - int rtn = __syscall_poll((intptr_t)fds, n, timeout); - if (rtn < 0) { - free(fds); - return -1; - } - - // Part 2: Translate the result of poll into the results of select(); - - if (readfds) FD_ZERO(readfds); - if (writefds) FD_ZERO(writefds); - if (exceptfds) FD_ZERO(exceptfds); - - int count = 0; - - if (rtn > 0) { - for (int i = 0; i < n; i++) { - int fd = fds[i].fd; - short revents = fds[i].revents; - if (revents) { - // Map POLLIN to readfds - // POLLHUP/POLLERR usually count as readable (EOF or Error) - if (readfds && (revents & POLLIN || revents & POLLHUP || revents & POLLERR)) { - FD_SET(fd, readfds); - count++; - } - // Map POLLOUT to writefds - // POLLERR usually counts as writable (so write fails immediately) - if (writefds && (revents & POLLOUT || revents & POLLERR)) { - FD_SET(fd, writefds); - count++; - } - // Map POLLPRI to exceptfds - if (exceptfds && (revents & POLLPRI)) { - FD_SET(fd, exceptfds); - count++; - } - } - } - } - - free(fds); - return count; -} -#endif diff --git a/system/lib/libc/musl/src/signal/block.c b/system/lib/libc/musl/src/signal/block.c index 736084bc10d27..cc8698f0bb7fb 100644 --- a/system/lib/libc/musl/src/signal/block.c +++ b/system/lib/libc/musl/src/signal/block.c @@ -30,21 +30,15 @@ static const unsigned long app_mask[] = { void __block_all_sigs(void *set) { -#ifndef __EMSCRIPTEN__ __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8); -#endif } void __block_app_sigs(void *set) { -#ifndef __EMSCRIPTEN__ __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8); -#endif } void __restore_sigs(void *set) { -#ifndef __EMSCRIPTEN__ __syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8); -#endif } diff --git a/system/lib/libc/musl/src/signal/getitimer.c b/system/lib/libc/musl/src/signal/getitimer.c index 251b2064fa202..36d1eb9dc6e99 100644 --- a/system/lib/libc/musl/src/signal/getitimer.c +++ b/system/lib/libc/musl/src/signal/getitimer.c @@ -1,18 +1,8 @@ #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ -#include -void __getitimer(int which, struct itimerval *old, double now); -#endif - int getitimer(int which, struct itimerval *old) { -#ifdef __EMSCRIPTEN__ - if (which > ITIMER_PROF) return EINVAL; - __getitimer(which, old, emscripten_get_now()); - return 0; -#else if (sizeof(time_t) > sizeof(long)) { long old32[4]; int r = __syscall(SYS_getitimer, which, old32); @@ -25,5 +15,4 @@ int getitimer(int which, struct itimerval *old) return __syscall_ret(r); } return syscall(SYS_getitimer, which, old); -#endif } diff --git a/system/lib/libc/musl/src/signal/setitimer.c b/system/lib/libc/musl/src/signal/setitimer.c index 94cc9c40326a8..0dfbeb4db5a7a 100644 --- a/system/lib/libc/musl/src/signal/setitimer.c +++ b/system/lib/libc/musl/src/signal/setitimer.c @@ -4,123 +4,8 @@ #define IS32BIT(x) !((x)+0x80000000ULL>>32) -#ifdef __EMSCRIPTEN__ -#include -#include -#include -#include -#include -#include -#include - -#include "emscripten_internal.h" - -// Timeouts can either fire directly from the JS event loop (which calls -// `_emscripten_timeout`), or from `_emscripten_check_timers` (which is called -// from `_emscripten_yield`). In order to be able to check the timers here we -// cache the current timeout and interval for each the 3 types of timer -// (ITIMER_PROF/ITIMER_VIRTUAL/ITIMER_REAL). -static double current_timeout_ms[3]; -static double current_intervals_ms[3]; - -#define MAX(a,b) ((a)>(b)?(a):(b)) - -void __getitimer(int which, struct itimerval *old, double now) -{ - double remaining_ms = MAX(current_timeout_ms[which] - now, 0); - old->it_value.tv_sec = remaining_ms / 1000; - old->it_value.tv_usec = remaining_ms * 1000; - old->it_interval.tv_sec = current_intervals_ms[which] / 1000; - old->it_interval.tv_usec = current_intervals_ms[which] * 1000; -} - -void _emscripten_timeout(int which, double now) -{ - int signum = SIGALRM; - if (which == ITIMER_PROF) - signum = SIGPROF; - else if (which == ITIMER_VIRTUAL) - signum = SIGVTALRM; - double next_timeout = 0.0; - if (current_intervals_ms[which]) { - // If time went backwards, schedule the next timer as if it didn't. - now = __builtin_wasm_max_f64(now, current_timeout_ms[which]); - // The next alarm is due 'interval' ms after the previous one. - // If this alarm was delayed, that is sooner than 'interval' ms - // from now. The delay could even be so long that we missed the - // next alarm(s) entirely. Schedule the alarm for the next - // multiple of 'interval' ms from the original due time. - uint64_t intervals = - (uint64_t)(now - current_timeout_ms[which]) / - (uint64_t)current_intervals_ms[which] + - 1; - current_timeout_ms[which] += - intervals * current_intervals_ms[which]; - next_timeout = current_timeout_ms[which] - now; - } else { - current_timeout_ms[which] = 0; - } - _setitimer_js(which, next_timeout); - raise(signum); -} - -bool _emscripten_check_timers(double now) -{ - // Timers always run on the main runtime thread. They are registered with - // _setitimer_js which is proxied to the main runtime thread. - assert(emscripten_is_main_runtime_thread()); - bool rtn = false; - for (int which = 0; which < 3; which++) { - if (current_timeout_ms[which]) { - // Only call out to JS to get the current time if it was not passed in - // *and* we have one or more timers set. - if (!now) - now = emscripten_get_now(); - if (now >= current_timeout_ms[which]) { - rtn = true; - _emscripten_timeout(which, now); - } - } - } - return rtn; -} - -double _emscripten_next_timer() -{ - assert(emscripten_is_main_runtime_thread()); - double next_timer = INFINITY; - for (int which = 0; which < 3; which++) { - if (current_timeout_ms[which]) { - next_timer = fmin(current_timeout_ms[which], next_timer); - } - } - // Avoid calling emscripten_get_now() unless we need to here. - if (next_timer != INFINITY) { - next_timer -= emscripten_get_now(); - } - return next_timer; -} -#endif - int setitimer(int which, const struct itimerval *restrict new, struct itimerval *restrict old) { -#ifdef __EMSCRIPTEN__ - if (which > ITIMER_PROF) return EINVAL; - double now = emscripten_get_now(); - if (old) { - __getitimer(which, old, now); - } - double timeout_ms = new->it_value.tv_sec * 1000 + new->it_value.tv_usec / 1000.0; - double interval_ms = new->it_interval.tv_sec * 1000 + new->it_interval.tv_usec / 1000.0; - if (new->it_value.tv_sec || new->it_value.tv_usec) { - current_timeout_ms[which] = now + timeout_ms; - current_intervals_ms[which] = interval_ms; - } else { - current_timeout_ms[which] = 0; - current_intervals_ms[which] = 0; - } - return _setitimer_js(which, timeout_ms); -#else if (sizeof(time_t) > sizeof(long)) { time_t is = new->it_interval.tv_sec, vs = new->it_value.tv_sec; long ius = new->it_interval.tv_usec, vus = new->it_value.tv_usec; @@ -138,5 +23,4 @@ int setitimer(int which, const struct itimerval *restrict new, struct itimerval return __syscall_ret(r); } return syscall(SYS_setitimer, which, new, old); -#endif } diff --git a/system/lib/libc/musl/src/stat/fchmod.c b/system/lib/libc/musl/src/stat/fchmod.c index 58badd5c01bb8..7a503eefc46ef 100644 --- a/system/lib/libc/musl/src/stat/fchmod.c +++ b/system/lib/libc/musl/src/stat/fchmod.c @@ -1,6 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#endif #include #include #include @@ -9,13 +6,8 @@ int fchmod(int fd, mode_t mode) { int ret = __syscall(SYS_fchmod, fd, mode); -#if __EMSCRIPTEN__ - if (ret != -EBADF || !__wasi_fd_is_valid(fd)) - return __syscall_ret(ret); -#else if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); -#endif char buf[15+3*sizeof(int)]; __procfdname(buf, fd); diff --git a/system/lib/libc/musl/src/stat/fchmodat.c b/system/lib/libc/musl/src/stat/fchmodat.c index 4a4539f05c89c..92c9d1b0e4a2c 100644 --- a/system/lib/libc/musl/src/stat/fchmodat.c +++ b/system/lib/libc/musl/src/stat/fchmodat.c @@ -5,9 +5,7 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag) { -#ifndef __EMSCRIPTEN__ if (!flag) return syscall(SYS_fchmodat, fd, path, mode); -#endif int ret = __syscall(SYS_fchmodat2, fd, path, mode, flag); if (ret != -ENOSYS) return __syscall_ret(ret); @@ -34,17 +32,9 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag) ret = stat(proc, &st); if (!ret) { if (S_ISLNK(st.st_mode)) ret = __syscall_ret(-EOPNOTSUPP); -#ifdef __EMSCRIPTEN__ - else ret = syscall(SYS_fchmodat2, AT_FDCWD, proc, mode, 0); -#else else ret = syscall(SYS_fchmodat, AT_FDCWD, proc, mode); -#endif } -#ifdef __EMSCRIPTEN__ - __wasi_fd_close(fd2); -#else __syscall(SYS_close, fd2); -#endif return ret; } diff --git a/system/lib/libc/musl/src/stat/fstatat.c b/system/lib/libc/musl/src/stat/fstatat.c index 631451268c590..9eed063b26bcf 100644 --- a/system/lib/libc/musl/src/stat/fstatat.c +++ b/system/lib/libc/musl/src/stat/fstatat.c @@ -7,11 +7,6 @@ #include #include "syscall.h" -/* XXX Emscripten: We #define kstat to stat so we can simply make the syscall - * without the extra copy. - * See arch/emscripten/kstat.h - */ -#ifndef __EMSCRIPTEN__ struct statx { uint32_t stx_mask; uint32_t stx_blksize; @@ -140,22 +135,10 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric return 0; } #endif -#endif int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag) { int ret; -#ifdef __EMSCRIPTEN__ - // some logic here copied from fstatat_kstat above - if (flag==AT_EMPTY_PATH && fd>=0 && !*path) - ret = __syscall(SYS_fstat, fd, st); - else if ((fd == AT_FDCWD || *path=='/') && !flag) - ret = __syscall(SYS_stat, path, st); - else if ((fd == AT_FDCWD || *path=='/') && flag==AT_SYMLINK_NOFOLLOW) - ret = __syscall(SYS_lstat, path, st); - else - ret = __syscall(SYS_fstatat, fd, path, st, flag); -#else #ifdef SYS_fstatat if (sizeof((struct kstat){0}.st_atime_sec) < sizeof(time_t)) { ret = fstatat_statx(fd, path, st, flag); @@ -164,7 +147,6 @@ int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int f ret = fstatat_kstat(fd, path, st, flag); #else ret = fstatat_statx(fd, path, st, flag); -#endif #endif return __syscall_ret(ret); } diff --git a/system/lib/libc/musl/src/stdio/__fdopen.c b/system/lib/libc/musl/src/stdio/__fdopen.c index ffc4df718a0b8..116e78e56d2a1 100644 --- a/system/lib/libc/musl/src/stdio/__fdopen.c +++ b/system/lib/libc/musl/src/stdio/__fdopen.c @@ -26,10 +26,8 @@ FILE *__fdopen(int fd, const char *mode) /* Impose mode restrictions */ if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process /* Apply close-on-exec flag */ if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); -#endif /* Set append mode on fd if opened for append */ if (*mode == 'a') { diff --git a/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c b/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c index 2f3acb831388e..183a5d5538955 100644 --- a/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c +++ b/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c @@ -8,9 +8,7 @@ FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t le f->fd = sys_open(filename, O_RDONLY|O_CLOEXEC); if (f->fd < 0) return 0; -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process __syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC); -#endif f->flags = F_NOWR | F_PERM; f->buf = buf + UNGET; diff --git a/system/lib/libc/musl/src/stdio/__lockfile.c b/system/lib/libc/musl/src/stdio/__lockfile.c index 3300a3c25495b..0f60a14990943 100644 --- a/system/lib/libc/musl/src/stdio/__lockfile.c +++ b/system/lib/libc/musl/src/stdio/__lockfile.c @@ -3,8 +3,7 @@ int __lockfile(FILE *f) { -#ifdef __EMSCRIPTEN_SHARED_MEMORY__ - int owner = f->lock, tid = CURRENT_THREAD_ID; + int owner = f->lock, tid = __pthread_self()->tid; if ((owner & ~MAYBE_WAITERS) == tid) return 0; owner = a_cas(&f->lock, 0, tid); @@ -14,14 +13,11 @@ int __lockfile(FILE *f) a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner) __futexwait(&f->lock, owner|MAYBE_WAITERS, 1); } -#endif return 1; } void __unlockfile(FILE *f) { -#ifdef __EMSCRIPTEN_SHARED_MEMORY__ if (a_swap(&f->lock, 0) & MAYBE_WAITERS) __wake(&f->lock, 1, 1); -#endif } diff --git a/system/lib/libc/musl/src/stdio/__stdio_close.c b/system/lib/libc/musl/src/stdio/__stdio_close.c index 7618de9309f32..3029132851878 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_close.c +++ b/system/lib/libc/musl/src/stdio/__stdio_close.c @@ -10,9 +10,5 @@ weak_alias(dummy, __aio_close); int __stdio_close(FILE *f) { -#ifdef __EMSCRIPTEN__ - return __wasi_syscall_ret(__wasi_fd_close(__aio_close(f->fd))); -#else return syscall(SYS_close, __aio_close(f->fd)); -#endif } diff --git a/system/lib/libc/musl/src/stdio/__stdio_read.c b/system/lib/libc/musl/src/stdio/__stdio_read.c index 392a4858281f3..ea675da34abbf 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_read.c +++ b/system/lib/libc/musl/src/stdio/__stdio_read.c @@ -9,16 +9,8 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) }; ssize_t cnt; -#if __EMSCRIPTEN__ - size_t num; - if (__wasi_syscall_ret(__wasi_fd_read(f->fd, (struct __wasi_iovec_t*)iov, 2, &num))) { - num = -1; - } - cnt = num; -#else cnt = iov[0].iov_len ? syscall(SYS_readv, f->fd, iov, 2) : syscall(SYS_read, f->fd, iov[1].iov_base, iov[1].iov_len); -#endif if (cnt <= 0) { f->flags |= cnt ? F_ERR : F_EOF; return 0; diff --git a/system/lib/libc/musl/src/stdio/__stdio_write.c b/system/lib/libc/musl/src/stdio/__stdio_write.c index cce9f6a16a558..d2d89475b0f94 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_write.c +++ b/system/lib/libc/musl/src/stdio/__stdio_write.c @@ -12,15 +12,7 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) int iovcnt = 2; ssize_t cnt; for (;;) { -#if __EMSCRIPTEN__ - size_t num; - if (__wasi_syscall_ret(__wasi_fd_write(f->fd, (struct __wasi_ciovec_t*)iov, iovcnt, &num))) { - num = -1; - } - cnt = num; -#else cnt = syscall(SYS_writev, f->fd, iov, iovcnt); -#endif if (cnt == rem) { f->wend = f->buf + f->buf_size; f->wpos = f->wbase = f->buf; diff --git a/system/lib/libc/musl/src/stdio/fopen.c b/system/lib/libc/musl/src/stdio/fopen.c index 97a5f816af077..80bc341e669b4 100644 --- a/system/lib/libc/musl/src/stdio/fopen.c +++ b/system/lib/libc/musl/src/stdio/fopen.c @@ -20,18 +20,12 @@ FILE *fopen(const char *restrict filename, const char *restrict mode) fd = sys_open(filename, flags, 0666); if (fd < 0) return 0; -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (flags & O_CLOEXEC) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); -#endif f = __fdopen(fd, mode); if (f) return f; -#ifdef __EMSCRIPTEN__ - __wasi_fd_close(fd); -#else __syscall(SYS_close, fd); -#endif return 0; } diff --git a/system/lib/libc/musl/src/stdio/fprintf.c b/system/lib/libc/musl/src/stdio/fprintf.c index b8b779767d55d..948743f7c8b78 100644 --- a/system/lib/libc/musl/src/stdio/fprintf.c +++ b/system/lib/libc/musl/src/stdio/fprintf.c @@ -1,4 +1,3 @@ -#include "stdio_impl.h" #include #include @@ -11,24 +10,3 @@ int fprintf(FILE *restrict f, const char *restrict fmt, ...) va_end(ap); return ret; } - -// XXX EMSCRIPTEN -int fiprintf(FILE *restrict f, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vfiprintf(f, fmt, ap); - va_end(ap); - return ret; -} - -int __small_fprintf(FILE *restrict f, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = __small_vfprintf(f, fmt, ap); - va_end(ap); - return ret; -} diff --git a/system/lib/libc/musl/src/stdio/freopen.c b/system/lib/libc/musl/src/stdio/freopen.c index 206b5c3eeff21..1641a4c5e92d5 100644 --- a/system/lib/libc/musl/src/stdio/freopen.c +++ b/system/lib/libc/musl/src/stdio/freopen.c @@ -20,10 +20,8 @@ FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *re fflush(f); if (!filename) { -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (fl&O_CLOEXEC) __syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC); -#endif fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC); if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0) goto fail; diff --git a/system/lib/libc/musl/src/stdio/getc.h b/system/lib/libc/musl/src/stdio/getc.h index f2700b41d2223..e24f9905c1f8c 100644 --- a/system/lib/libc/musl/src/stdio/getc.h +++ b/system/lib/libc/musl/src/stdio/getc.h @@ -16,7 +16,7 @@ static int locking_getc(FILE *f) static inline int do_getc(FILE *f) { int l = f->lock; - if (l < 0 || l && (l & ~MAYBE_WAITERS) == CURRENT_THREAD_ID) + if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid) return getc_unlocked(f); return locking_getc(f); } diff --git a/system/lib/libc/musl/src/stdio/printf.c b/system/lib/libc/musl/src/stdio/printf.c index c1722dea59086..cebfe404fb97d 100644 --- a/system/lib/libc/musl/src/stdio/printf.c +++ b/system/lib/libc/musl/src/stdio/printf.c @@ -1,4 +1,3 @@ -#include "stdio_impl.h" #include #include @@ -11,25 +10,3 @@ int printf(const char *restrict fmt, ...) va_end(ap); return ret; } - -// XXX EMSCRIPTEN -int iprintf(const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vfiprintf(stdout, fmt, ap); - va_end(ap); - return ret; -} - -int __small_printf(const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = __small_vfprintf(stdout, fmt, ap); - va_end(ap); - return ret; -} - diff --git a/system/lib/libc/musl/src/stdio/putc.h b/system/lib/libc/musl/src/stdio/putc.h index a284f853f3b02..2014c4ec4af9c 100644 --- a/system/lib/libc/musl/src/stdio/putc.h +++ b/system/lib/libc/musl/src/stdio/putc.h @@ -16,7 +16,7 @@ static int locking_putc(int c, FILE *f) static inline int do_putc(int c, FILE *f) { int l = f->lock; - if (l < 0 || l && (l & ~MAYBE_WAITERS) == CURRENT_THREAD_ID) + if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid) return putc_unlocked(c, f); return locking_putc(c, f); } diff --git a/system/lib/libc/musl/src/stdio/sprintf.c b/system/lib/libc/musl/src/stdio/sprintf.c index 0b984e5e9951b..9dff524c0925e 100644 --- a/system/lib/libc/musl/src/stdio/sprintf.c +++ b/system/lib/libc/musl/src/stdio/sprintf.c @@ -1,4 +1,3 @@ -#include "stdio_impl.h" #include #include @@ -11,25 +10,3 @@ int sprintf(char *restrict s, const char *restrict fmt, ...) va_end(ap); return ret; } - -// XXX EMSCRIPTEN -int siprintf(char *restrict s, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = vsiprintf(s, fmt, ap); - va_end(ap); - return ret; -} - -int __small_sprintf(char *restrict s, const char *restrict fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - ret = __small_vsprintf(s, fmt, ap); - va_end(ap); - return ret; -} - diff --git a/system/lib/libc/musl/src/stdio/stdout.c b/system/lib/libc/musl/src/stdio/stdout.c index 62cf40220a5c4..4985a417bdda7 100644 --- a/system/lib/libc/musl/src/stdio/stdout.c +++ b/system/lib/libc/musl/src/stdio/stdout.c @@ -1,19 +1,5 @@ #include "stdio_impl.h" -#if __EMSCRIPTEN__ -// Emscripten doesn't support terminal seeking. -static off_t __emscripten_stdout_seek(FILE *f, off_t off, int whence) -{ - return 0; -} - -// No special work is needed to close stdout. -static int __emscripten_stdout_close(FILE *f) -{ - return 0; -} -#endif - #undef stdout static unsigned char buf[BUFSIZ+UNGET]; @@ -23,16 +9,9 @@ hidden FILE __stdout_FILE = { .fd = 1, .flags = F_PERM | F_NORD, .lbf = '\n', -#if __EMSCRIPTEN__ - // avoid stout_write which adds special terminal window size handling, which emscripten doesn't support anyhow - .write = __stdio_write, - .seek = __emscripten_stdout_seek, - .close = __emscripten_stdout_close, -#else .write = __stdout_write, .seek = __stdio_seek, .close = __stdio_close, -#endif .lock = -1, }; FILE *const stdout = &__stdout_FILE; diff --git a/system/lib/libc/musl/src/stdio/tmpfile.c b/system/lib/libc/musl/src/stdio/tmpfile.c index 81f8f0cdc7e7b..2fa8803fc2312 100644 --- a/system/lib/libc/musl/src/stdio/tmpfile.c +++ b/system/lib/libc/musl/src/stdio/tmpfile.c @@ -21,11 +21,7 @@ FILE *tmpfile(void) __syscall(SYS_unlinkat, AT_FDCWD, s, 0); #endif f = __fdopen(fd, "w+"); -#ifdef __EMSCRIPTEN__ - if (!f) __wasi_fd_close(fd); -#else if (!f) __syscall(SYS_close, fd); -#endif return f; } } diff --git a/system/lib/libc/musl/src/stdio/vfprintf.c b/system/lib/libc/musl/src/stdio/vfprintf.c index c0542b599024c..497c5e19372dc 100644 --- a/system/lib/libc/musl/src/stdio/vfprintf.c +++ b/system/lib/libc/musl/src/stdio/vfprintf.c @@ -11,39 +11,6 @@ #include #include -#ifndef EMSCRIPTEN_PRINTF_LONG_DOUBLE -// XXX EMSCRIPTEN - while wasm32 has long double = float128, we don't support -// printing at full precision by default. instead, we lower to -// 64-bit double. These macros makes our changes a little less -// invasive. -typedef double long_double; -#undef LDBL_TRUE_MIN -#define LDBL_TRUE_MIN DBL_DENORM_MIN -#undef LDBL_MIN -#define LDBL_MIN DBL_MIN -#undef LDBL_MAX -#define LDBL_MAX DBL_MAX -#undef LDBL_EPSILON -#define LDBL_EPSILON DBL_EPSILON -#undef LDBL_MANT_DIG -#define LDBL_MANT_DIG DBL_MANT_DIG -#undef LDBL_MIN_EXP -#define LDBL_MIN_EXP DBL_MIN_EXP -#undef LDBL_MAX_EXP -#define LDBL_MAX_EXP DBL_MAX_EXP -#undef LDBL_DIG -#define LDBL_DIG DBL_DIG -#undef LDBL_MIN_10_EXP -#define LDBL_MIN_10_EXP DBL_MIN_10_EXP -#undef LDBL_MAX_10_EXP -#define LDBL_MAX_10_EXP DBL_MAX_10_EXP -#undef frexpl -#define frexpl(x, exp) frexp(x, exp) -#else // EMSCRIPTEN_FULL_LONG_DOUBLE_PRINTING -// XXX EMSCRIPTEN - full long double printing support -typedef long double long_double; -#endif - /* Some useful macros */ #define MAX(a,b) ((a)>(b) ? (a) : (b)) @@ -87,9 +54,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, S('c') = INT, S('C') = UINT, S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, -#ifndef __EMSCRIPTEN__ // 'm' is a gnu extension, and strerror brings in 2.5K of strings S('m') = NOARG, -#endif S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, }, { /* 1: l-prefixed */ @@ -137,20 +102,11 @@ static const unsigned char states[]['z'-'A'+1] = { union arg { uintmax_t i; - long_double f; + long double f; void *p; }; -// XXX EMSCRIPTEN - split out long double, so we don't always link in -// long double support for float printf. -typedef void (*pop_arg_long_double_t)(union arg *arg, va_list *ap); - -static void pop_arg_long_double(union arg *arg, va_list *ap) -{ - arg->f = va_arg(*ap, long double); -} - -static void pop_arg(union arg *arg, int type, va_list *ap, pop_arg_long_double_t pop_arg_long_double) +static void pop_arg(union arg *arg, int type, va_list *ap) { switch (type) { case PTR: arg->p = va_arg(*ap, void *); @@ -170,7 +126,7 @@ static void pop_arg(union arg *arg, int type, va_list *ap, pop_arg_long_double_t break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t); break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *); break; case DBL: arg->f = va_arg(*ap, double); - break; case LDBL: pop_arg_long_double(arg, ap); + break; case LDBL: arg->f = va_arg(*ap, long double); } } @@ -218,16 +174,10 @@ static char *fmt_u(uintmax_t x, char *s) * depends on the float.h constants being right. If they are wrong, it * may overflow the stack. */ #if LDBL_MANT_DIG == 53 -typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long_double)]; +typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; #endif -// XXX EMSCRIPTEN - access fmt_fp indirectly, so that iprintf doesn't -// get it linked in -// also use a double argument here, as mentioned before, -// we print float128s at double precision -typedef int (*fmt_fp_t)(FILE *f, long_double y, int w, int p, int fl, int t); - -static int fmt_fp(FILE *f, long_double y, int w, int p, int fl, int t) +static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) { uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion @@ -261,7 +211,7 @@ static int fmt_fp(FILE *f, long_double y, int w, int p, int fl, int t) if (y) e2--; if ((t|32)=='a') { - long_double round = 8.0; + long double round = 8.0; int re; if (t&32) prefix += 9; @@ -368,8 +318,8 @@ static int fmt_fp(FILE *f, long_double y, int w, int p, int fl, int t) x = *d % i; /* Are there any significant digits past j? */ if (x || d+1!=z) { - long_double round = 2/LDBL_EPSILON; - long_double small; + long double round = 2/LDBL_EPSILON; + long double small; if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1))) round += 2; if (x=0) { if (!f) nl_type[argpos]=st; else arg=nl_arg[argpos]; - } else if (f) pop_arg(&arg, st, ap, pop_arg_long_double); + } else if (f) pop_arg(&arg, st, ap); else return 0; } @@ -645,10 +593,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, *(a=z-(p=1))=arg.i; fl &= ~ZERO_PAD; break; -#ifndef __EMSCRIPTEN__ // 'm' is a gnu extension, and strerror brings in 2.5K of strings case 'm': if (1) a = strerror(errno); else -#endif case 's': a = arg.p ? arg.p : "(null)"; z = a + strnlen(a, p<0 ? INT_MAX : p); @@ -702,7 +648,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, if (!l10n) return 0; for (i=1; i<=NL_ARGMAX && nl_type[i]; i++) - pop_arg(nl_arg+i, nl_type[i], ap, pop_arg_long_double); + pop_arg(nl_arg+i, nl_type[i], ap); for (; i<=NL_ARGMAX && !nl_type[i]; i++); if (i<=NL_ARGMAX) goto inval; return 1; @@ -715,9 +661,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, return -1; } -// XXX EMSCRIPTEN: pass in fmt_fp and pop_arg as a function pointer, so iprintf/__small_printf don't -// force linking in of floating-point code. -int __vfprintf_internal(FILE *restrict f, const char *restrict fmt, va_list ap, fmt_fp_t fmt_fp, pop_arg_long_double_t pop_arg_long_double) +int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) { va_list ap2; int nl_type[NL_ARGMAX+1] = {0}; @@ -728,7 +672,7 @@ int __vfprintf_internal(FILE *restrict f, const char *restrict fmt, va_list ap, /* the copy allows passing va_list* even if va_list is an array */ va_copy(ap2, ap); - if (printf_core(0, fmt, &ap2, nl_arg, nl_type, fmt_fp, pop_arg_long_double) < 0) { + if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) { va_end(ap2); return -1; } @@ -743,7 +687,7 @@ int __vfprintf_internal(FILE *restrict f, const char *restrict fmt, va_list ap, f->wpos = f->wbase = f->wend = 0; } if (!f->wend && __towrite(f)) ret = -1; - else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type, fmt_fp, pop_arg_long_double); + else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type); if (saved_buf) { f->write(f, 0, 0); if (!f->wpos) ret = -1; @@ -757,20 +701,3 @@ int __vfprintf_internal(FILE *restrict f, const char *restrict fmt, va_list ap, va_end(ap2); return ret; } - -int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) -{ - return __vfprintf_internal(f, fmt, ap, fmt_fp, pop_arg_long_double); -} - -// XXX EMSCRIPTEN -int vfiprintf(FILE *restrict f, const char *restrict fmt, va_list ap) -{ - return __vfprintf_internal(f, fmt, ap, NULL, NULL); -} - -// XXX EMSCRIPTEN -int __small_vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) -{ - return __vfprintf_internal(f, fmt, ap, fmt_fp, NULL); -} diff --git a/system/lib/libc/musl/src/stdio/vsnprintf.c b/system/lib/libc/musl/src/stdio/vsnprintf.c index 4d18b50450ef6..409b9c8583db8 100644 --- a/system/lib/libc/musl/src/stdio/vsnprintf.c +++ b/system/lib/libc/musl/src/stdio/vsnprintf.c @@ -48,58 +48,3 @@ int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) *c.s = 0; return vfprintf(&f, fmt, ap); } - -// XXX EMSCRIPTEN -int vsniprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) -{ - int r; - char b; - FILE f = { .lbf = EOF, .write = sn_write, .lock = -1 }; - - if (n-1 > INT_MAX-1) { - if (n) { - errno = EOVERFLOW; - return -1; - } - s = &b; - n = 1; - } - - /* Ensure pointers don't wrap if "infinite" n is passed in */ - if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; - f.buf_size = n; - f.buf = f.wpos = (void *)s; - f.wbase = f.wend = (void *)(s+n); - r = vfiprintf(&f, fmt, ap); - - /* Null-terminate, overwriting last char if dest buffer is full */ - if (n) f.wpos[-(f.wpos == f.wend)] = 0; - return r; -} - -int __small_vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) -{ - int r; - char b; - FILE f = { .lbf = EOF, .write = sn_write, .lock = -1 }; - - if (n-1 > INT_MAX-1) { - if (n) { - errno = EOVERFLOW; - return -1; - } - s = &b; - n = 1; - } - - /* Ensure pointers don't wrap if "infinite" n is passed in */ - if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; - f.buf_size = n; - f.buf = f.wpos = (void *)s; - f.wbase = f.wend = (void *)(s+n); - r = __small_vfprintf(&f, fmt, ap); - - /* Null-terminate, overwriting last char if dest buffer is full */ - if (n) f.wpos[-(f.wpos == f.wend)] = 0; - return r; -} diff --git a/system/lib/libc/musl/src/stdio/vsprintf.c b/system/lib/libc/musl/src/stdio/vsprintf.c index c171886f6abf7..c57349d4d888d 100644 --- a/system/lib/libc/musl/src/stdio/vsprintf.c +++ b/system/lib/libc/musl/src/stdio/vsprintf.c @@ -1,4 +1,3 @@ -#include "stdio_impl.h" #include #include @@ -6,15 +5,3 @@ int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) { return vsnprintf(s, INT_MAX, fmt, ap); } - -// XXX EMSCRIPTEN -int vsiprintf(char *restrict s, const char *restrict fmt, va_list ap) -{ - return vsniprintf(s, INT_MAX, fmt, ap); -} - -int __small_vsprintf(char *restrict s, const char *restrict fmt, va_list ap) -{ - return __small_vsnprintf(s, INT_MAX, fmt, ap); -} - diff --git a/system/lib/libc/musl/src/stdlib/strtol.c b/system/lib/libc/musl/src/stdlib/strtol.c index 29a7f1ad74965..bfefea69d1c4f 100644 --- a/system/lib/libc/musl/src/stdlib/strtol.c +++ b/system/lib/libc/musl/src/stdlib/strtol.c @@ -5,89 +5,6 @@ #include #include -#ifdef __EMSCRIPTEN__ -#include - -// Loosely based on __intscan but simplified, and optimized for size -// - Doesn't use FILE or getc/ungetc, just operates directly on memory -// - Avoids lookup table -// - Avoids special cases loops for certain bases -// - Skips an early exit with EINVAL when char 0 is greater than base. Its not -// clear this was correct, and glibc seems not do this either. -static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim) { - int neg=0; - unsigned long long y=0; - const char* orig = s; - - if (base > 36) { - errno = EINVAL; - return 0; - } - - while (*s && isspace(*s)) { s++; }; - - // Handle sign - if (*s=='+' || *s=='-') { - neg = -(*s=='-'); - s++; - } - - int found_digit = 0; - - // Handle hex/octal prefix 0x/00 - if ((base == 0 || base == 16) && *s=='0') { - found_digit = 1; - s++; - if ((*s|32)=='x') { - s++; - base = 16; - } else if (base == 0) { - base = 8; - } - } else if (base == 0) { - base = 10; - } - - int val; - int overflow = 0; - for (y=0; ; s++) { - if ('0' <= *s && *s <= '9') val = *s -'0'; - else if ('a' <= *s && *s <= 'z') val = 10 + *s -'a'; - else if ('A' <= *s && *s <= 'Z') val = 10 + *s -'A'; - else break; - if (val>=base) break; - if (y > ULLONG_MAX/base || (base*y>ULLONG_MAX-val)) { - overflow = 1; - continue; - } - found_digit = 1; - y = y*base + val; - } - if (p) { - if (found_digit) { - *p = (char*)s; - } else { - *p = (char*)orig; - } - } - if (overflow) { - // We exit'd the above loop due to overflow - errno = ERANGE; - y = lim; - if (lim&1) neg = 0; - } - if (y>=lim) { - if (!(lim&1) && !neg) { - errno = ERANGE; - return lim-1; - } else if (y>lim) { - errno = ERANGE; - return lim; - } - } - return (y^neg)-neg; -} -#else static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim) { FILE f; @@ -100,7 +17,6 @@ static unsigned long long strtox(const char *s, char **p, int base, unsigned lon } return y; } -#endif unsigned long long strtoull(const char *restrict s, char **restrict p, int base) { diff --git a/system/lib/libc/musl/src/string/memchr.c b/system/lib/libc/musl/src/string/memchr.c index bad4e75cc3f38..65f0d789b2c9a 100644 --- a/system/lib/libc/musl/src/string/memchr.c +++ b/system/lib/libc/musl/src/string/memchr.c @@ -12,8 +12,7 @@ void *memchr(const void *src, int c, size_t n) { const unsigned char *s = src; c = (unsigned char)c; -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--); if (n && *s != c) { typedef size_t __attribute__((__may_alias__)) word; diff --git a/system/lib/libc/musl/src/string/memcmp.c b/system/lib/libc/musl/src/string/memcmp.c index c93cf8cc97330..bdbce9f0f563c 100644 --- a/system/lib/libc/musl/src/string/memcmp.c +++ b/system/lib/libc/musl/src/string/memcmp.c @@ -1,32 +1,8 @@ -#if __EMSCRIPTEN__ -#include -#endif #include int memcmp(const void *vl, const void *vr, size_t n) { const unsigned char *l=vl, *r=vr; - -// XXX EMSCRIPTEN: add an optimized version. -#if !defined(EMSCRIPTEN_OPTIMIZE_FOR_OZ) && !__has_feature(address_sanitizer) - // If we have enough bytes, and everything is aligned, loop on words instead - // of single bytes. - if (n >= 4 && !((((uintptr_t)l) & 3) | (((uintptr_t)r) & 3))) { - while (n >= 4) { - if (*((uint32_t *)l) != *((uint32_t *)r)) { - // Go to the single-byte loop to find the specific byte. - break; - } - l += 4; - r += 4; - n -= 4; - } - } -#endif - -#if defined(EMSCRIPTEN_OPTIMIZE_FOR_OZ) -#pragma clang loop unroll(disable) -#endif for (; n && *l == *r; n--, l++, r++); return n ? *l-*r : 0; } diff --git a/system/lib/libc/musl/src/string/stpcpy.c b/system/lib/libc/musl/src/string/stpcpy.c index b3685bf5ac2dc..4db46a9e50b2f 100644 --- a/system/lib/libc/musl/src/string/stpcpy.c +++ b/system/lib/libc/musl/src/string/stpcpy.c @@ -1,7 +1,6 @@ #include #include #include -#include "libc.h" #define ALIGN (sizeof(size_t)) #define ONES ((size_t)-1/UCHAR_MAX) @@ -10,8 +9,7 @@ char *__stpcpy(char *restrict d, const char *restrict s) { -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ typedef size_t __attribute__((__may_alias__)) word; word *wd; const word *ws; diff --git a/system/lib/libc/musl/src/string/stpncpy.c b/system/lib/libc/musl/src/string/stpncpy.c index 2e3f67ef3abce..f57fa6b71bf3d 100644 --- a/system/lib/libc/musl/src/string/stpncpy.c +++ b/system/lib/libc/musl/src/string/stpncpy.c @@ -1,7 +1,6 @@ #include #include #include -#include "libc.h" #define ALIGN (sizeof(size_t)-1) #define ONES ((size_t)-1/UCHAR_MAX) @@ -10,8 +9,7 @@ char *__stpncpy(char *restrict d, const char *restrict s, size_t n) { -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ typedef size_t __attribute__((__may_alias__)) word; word *wd; const word *ws; @@ -31,3 +29,4 @@ char *__stpncpy(char *restrict d, const char *restrict s, size_t n) } weak_alias(__stpncpy, stpncpy); + diff --git a/system/lib/libc/musl/src/string/strchrnul.c b/system/lib/libc/musl/src/string/strchrnul.c index 0ead0dffdcdf6..39e2635b3064d 100644 --- a/system/lib/libc/musl/src/string/strchrnul.c +++ b/system/lib/libc/musl/src/string/strchrnul.c @@ -1,7 +1,6 @@ #include #include #include -#include "libc.h" #define ALIGN (sizeof(size_t)) #define ONES ((size_t)-1/UCHAR_MAX) @@ -13,8 +12,7 @@ char *__strchrnul(const char *s, int c) c = (unsigned char)c; if (!c) return (char *)s + strlen(s); -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ typedef size_t __attribute__((__may_alias__)) word; const word *w; for (; (uintptr_t)s % ALIGN; s++) diff --git a/system/lib/libc/musl/src/string/strlen.c b/system/lib/libc/musl/src/string/strlen.c index aab0719519f6e..309990f029f0c 100644 --- a/system/lib/libc/musl/src/string/strlen.c +++ b/system/lib/libc/musl/src/string/strlen.c @@ -10,8 +10,7 @@ size_t strlen(const char *s) { const char *a = s; -/* XXX EMSCRIPTEN: add __has_feature check */ -#if defined(__GNUC__) && !__has_feature(address_sanitizer) +#ifdef __GNUC__ typedef size_t __attribute__((__may_alias__)) word; const word *w; for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a; diff --git a/system/lib/libc/musl/src/temp/__randname.c b/system/lib/libc/musl/src/temp/__randname.c index 62152de05b5ed..e9b970f1f6360 100644 --- a/system/lib/libc/musl/src/temp/__randname.c +++ b/system/lib/libc/musl/src/temp/__randname.c @@ -12,11 +12,6 @@ char *__randname(char *template) __clock_gettime(CLOCK_REALTIME, &ts); r = ts.tv_sec + ts.tv_nsec + __pthread_self()->tid * 65537UL; - - /* XXX EMSCRIPTEN: avoid repeating the same result when __clock_gettime does not change between calls. */ - static unsigned int counter = 0; - r += counter++; - for (i=0; i<6; i++, r>>=5) template[i] = 'A'+(r&15)+(r&16)*2; diff --git a/system/lib/libc/musl/src/thread/__timedwait.c b/system/lib/libc/musl/src/thread/__timedwait.c index 9e3ccc9849257..666093be98516 100644 --- a/system/lib/libc/musl/src/thread/__timedwait.c +++ b/system/lib/libc/musl/src/thread/__timedwait.c @@ -1,17 +1,10 @@ #include #include #include -#ifdef __EMSCRIPTEN__ -#include -#include -#include -#else #include "futex.h" -#endif #include "syscall.h" #include "pthread_impl.h" -#ifndef __EMSCRIPTEN__ #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) @@ -32,7 +25,6 @@ static int __futex4_cp(volatile void *addr, int op, int val, const struct timesp if (r != -ENOSYS) return r; return __syscall_cp(SYS_futex, addr, op & ~FUTEX_PRIVATE, val, to); } -#endif static volatile int dummy = 0; weak_alias(dummy, __eintr_valid_flag); @@ -57,12 +49,7 @@ int __timedwait_cp(volatile int *addr, int val, top = &to; } -#ifdef __EMSCRIPTEN__ - double msecs_to_sleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY; - r = -emscripten_futex_wait((void*)addr, val, msecs_to_sleep); -#else r = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top); -#endif if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0; /* Mitigate bug in old kernels wrongly reporting EINTR for non- * interrupting (SA_RESTART) signal handlers. This is only practical @@ -78,14 +65,7 @@ int __timedwait(volatile int *addr, int val, { int cs, r; __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); -#ifdef __EMSCRIPTEN__ - emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_WAITMUTEX); -#endif r = __timedwait_cp(addr, val, clk, at, priv); -#ifdef __EMSCRIPTEN__ - emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_WAITMUTEX, EM_THREAD_STATUS_RUNNING); -#endif __pthread_setcancelstate(cs, 0); - return r; } diff --git a/system/lib/libc/musl/src/thread/__wait.c b/system/lib/libc/musl/src/thread/__wait.c index 66a140bd69401..dc33c1a30992e 100644 --- a/system/lib/libc/musl/src/thread/__wait.c +++ b/system/lib/libc/musl/src/thread/__wait.c @@ -1,8 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#include -#endif - #include "pthread_impl.h" void __wait(volatile int *addr, volatile int *waiters, int val, int priv) @@ -15,12 +10,8 @@ void __wait(volatile int *addr, volatile int *waiters, int val, int priv) } if (waiters) a_inc(waiters); while (*addr==val) { -#ifdef __EMSCRIPTEN__ - emscripten_futex_wait((void*)addr, val, INFINITY); -#else __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); -#endif } if (waiters) a_dec(waiters); } diff --git a/system/lib/libc/musl/src/thread/pthread_atfork.c b/system/lib/libc/musl/src/thread/pthread_atfork.c index f1b40eb57ddc0..26d325438cec6 100644 --- a/system/lib/libc/musl/src/thread/pthread_atfork.c +++ b/system/lib/libc/musl/src/thread/pthread_atfork.c @@ -3,7 +3,6 @@ #include "libc.h" #include "lock.h" -#ifndef __EMSCRIPTEN__ // XXX Emscripten fork() is not supported: pthread_atfork is a no-op #define malloc __libc_malloc #define calloc undef #define realloc undef @@ -37,13 +36,9 @@ void __fork_handler(int who) UNLOCK(lock); } } -#endif int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) { -#ifdef __EMSCRIPTEN__ // XXX Emscripten fork() is not supported: pthread_atfork is a no-op - return 0; -#else struct atfork_funcs *new = malloc(sizeof *new); if (!new) return ENOMEM; @@ -57,5 +52,4 @@ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(vo funcs = new; UNLOCK(lock); return 0; -#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_attr_get.c b/system/lib/libc/musl/src/thread/pthread_attr_get.c index 73e30a5f01214..f12ff442548dd 100644 --- a/system/lib/libc/musl/src/thread/pthread_attr_get.c +++ b/system/lib/libc/musl/src/thread/pthread_attr_get.c @@ -37,12 +37,8 @@ int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope) int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size) { -/// XXX musl is not standard-conforming? It should not report EINVAL if _a_stackaddr is zero, and it should -/// report EINVAL if a is null: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getstack.html - if (!a) return EINVAL; -// if (!a->_a_stackaddr) -// return EINVAL; - + if (!a->_a_stackaddr) + return EINVAL; *size = a->_a_stacksize; *addr = (void *)(a->_a_stackaddr - *size); return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_barrier_wait.c b/system/lib/libc/musl/src/thread/pthread_barrier_wait.c index 0d73d7fd33267..cc2a8bbf58a9c 100644 --- a/system/lib/libc/musl/src/thread/pthread_barrier_wait.c +++ b/system/lib/libc/musl/src/thread/pthread_barrier_wait.c @@ -1,7 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#endif - #include "pthread_impl.h" static int pshared_barrier_wait(pthread_barrier_t *b) @@ -87,14 +83,9 @@ int pthread_barrier_wait(pthread_barrier_t *b) while (spins-- && !inst->finished) a_spin(); a_inc(&inst->finished); - while (inst->finished == 1) { -#ifdef __EMSCRIPTEN__ - emscripten_futex_wait(&inst->finished, 1, INFINITY); -#else + while (inst->finished == 1) __syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS || __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0); -#endif - } return PTHREAD_BARRIER_SERIAL_THREAD; } diff --git a/system/lib/libc/musl/src/thread/pthread_cancel.c b/system/lib/libc/musl/src/thread/pthread_cancel.c index 953c5a08f7e43..139a6fc84e81d 100644 --- a/system/lib/libc/musl/src/thread/pthread_cancel.c +++ b/system/lib/libc/musl/src/thread/pthread_cancel.c @@ -8,13 +8,12 @@ hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c(); long __cancel() { pthread_t self = __pthread_self(); - if (self->canceldisable == PTHREAD_CANCEL_ENABLE) + if (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync) pthread_exit(PTHREAD_CANCELED); self->canceldisable = PTHREAD_CANCEL_DISABLE; return -ECANCELED; } -#ifndef __EMSCRIPTEN__ long __syscall_cp_asm(volatile void *, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t); @@ -72,7 +71,6 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) __syscall(SYS_tkill, self->tid, SIGCANCEL); } -#endif void __testcancel() { @@ -81,7 +79,6 @@ void __testcancel() __cancel(); } -#ifndef __EMSCRIPTEN__ static void init_cancellation() { struct sigaction sa = { @@ -91,30 +88,19 @@ static void init_cancellation() memset(&sa.sa_mask, -1, _NSIG/8); __libc_sigaction(SIGCANCEL, &sa, 0); } -#endif int pthread_cancel(pthread_t t) { -#ifndef __EMSCRIPTEN__ static int init; if (!init) { init_cancellation(); init = 1; } -#endif a_store(&t->cancel, 1); if (t == pthread_self()) { if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync) pthread_exit(PTHREAD_CANCELED); return 0; } -#ifdef __EMSCRIPTEN__ - // Wake the target thread in case it is in emscripten_futex_wait. Normally, - // this is only required when the target is the main runtime thread and there - // is an event added to its system queue. - // However, all threads need to be interrupted like this in the case they are - // cancelled. - _emscripten_thread_notify(t); -#endif return pthread_kill(t, SIGCANCEL); } diff --git a/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c b/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c index edd5a571a4585..6b761455c47f0 100644 --- a/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c +++ b/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c @@ -48,19 +48,9 @@ static inline void unlock(volatile int *l) static inline void unlock_requeue(volatile int *l, volatile int *r, int w) { a_store(l, 0); -#ifdef __EMSCRIPTEN__ - // Here the intent is to wake one waiter, and requeue all other waiters from waiting on address 'l' - // to wait on address 'r' instead. This is not possible at the moment with SharedArrayBuffer Atomics, - // as it does not have a "wake X waiters and requeue the rest" primitive. However this kind of - // primitive is strictly not needed, since it is more like an optimization to avoid spuriously waking - // all waiters, just to make them wait on another location immediately afterwards. Here we do exactly - // that: wake every waiter. - emscripten_futex_wake(l, INT_MAX); -#else if (w) __wake(l, 1, 1); else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r); -#endif } enum { @@ -75,13 +65,6 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restri int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp; volatile int *fut; -#ifdef __EMSCRIPTEN__ - // TODO: Optimize this away in MINIMAL_RUNTIME. - if (emscripten_is_main_browser_thread()) { - emscripten_check_blocking_allowed(); - } -#endif - if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid) return EPERM; diff --git a/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c b/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c index 809cc68d20a51..51453e0480a82 100644 --- a/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c +++ b/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c @@ -3,9 +3,6 @@ int pthread_condattr_setpshared(pthread_condattr_t *a, int pshared) { if (pshared > 1U) return EINVAL; -#ifdef __EMSCRIPTEN__ - if (pshared) return ENOTSUP; -#endif a->__attr &= 0x7fffffff; a->__attr |= (unsigned)pshared<<31; return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_detach.c b/system/lib/libc/musl/src/thread/pthread_detach.c index c25882cca4ac1..d73a500e79adc 100644 --- a/system/lib/libc/musl/src/thread/pthread_detach.c +++ b/system/lib/libc/musl/src/thread/pthread_detach.c @@ -3,25 +3,9 @@ static int __pthread_detach(pthread_t t) { -#ifdef __EMSCRIPTEN__ - // XXX EMSCRIPTEN: Add check for invalid (already joined) thread. Again - // for the benefit of the conformance tests. - if (!_emscripten_thread_is_valid(t)) - return ESRCH; -#endif /* If the cas fails, detach state is either already-detached * or exiting/exited, and pthread_join will trap or cleanup. */ -#ifdef __EMSCRIPTEN__ - int old_state = a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED); - if (old_state != DT_JOINABLE) { - // Even though the man page says this is undefined behaviour to attempt to - // detach an already-detached thread we have several tests in the posixtest - // suite that depend on this (pthread_join.c) - if (old_state == DT_DETACHED) - return EINVAL; -#else if (a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED) != DT_JOINABLE) { -#endif int cs; __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); __pthread_join(t, 0); @@ -32,5 +16,3 @@ static int __pthread_detach(pthread_t t) weak_alias(__pthread_detach, pthread_detach); weak_alias(__pthread_detach, thrd_detach); -// XXX EMSCRIPTEN: add extra alias for asan. -weak_alias(__pthread_detach, emscripten_builtin_pthread_detach); diff --git a/system/lib/libc/musl/src/thread/pthread_getattr_np.c b/system/lib/libc/musl/src/thread/pthread_getattr_np.c index 5f5246133bc32..2881831f8c2fa 100644 --- a/system/lib/libc/musl/src/thread/pthread_getattr_np.c +++ b/system/lib/libc/musl/src/thread/pthread_getattr_np.c @@ -8,10 +8,6 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a) *a = (pthread_attr_t){0}; a->_a_detach = t->detach_state>=DT_DETACHED; a->_a_guardsize = t->guard_size; -#ifdef __EMSCRIPTEN__ - a->_a_stackaddr = (uintptr_t)t->stack; - a->_a_stacksize = t->stack_size; -#else if (t->stack) { a->_a_stackaddr = (uintptr_t)t->stack; a->_a_stacksize = t->stack_size; @@ -24,6 +20,5 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a) l += PAGE_SIZE; a->_a_stacksize = l; } -#endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_getconcurrency.c b/system/lib/libc/musl/src/thread/pthread_getconcurrency.c index 4ab5f1b94aeee..269429a8abca8 100644 --- a/system/lib/libc/musl/src/thread/pthread_getconcurrency.c +++ b/system/lib/libc/musl/src/thread/pthread_getconcurrency.c @@ -1,7 +1,5 @@ #include -// XXX Emscripten marked as obsolescent in pthreads specification: -// http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getconcurrency.html int pthread_getconcurrency() { return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c b/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c index 62355f43ef47d..9df14fb689524 100644 --- a/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c +++ b/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c @@ -2,11 +2,6 @@ int pthread_getcpuclockid(pthread_t t, clockid_t *clockid) { -#ifdef __EMSCRIPTEN__ // XXX Emscipten per-thread CPU time clocks are not supported - // pthread API recommends returning this error when "Per-thread CPU time clocks are not supported by the system." - return ENOENT; -#else *clockid = (-t->tid-1)*8U + 6; return 0; -#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_getschedparam.c b/system/lib/libc/musl/src/thread/pthread_getschedparam.c index d5931b7b64e5c..c098befb1b7f0 100644 --- a/system/lib/libc/musl/src/thread/pthread_getschedparam.c +++ b/system/lib/libc/musl/src/thread/pthread_getschedparam.c @@ -3,10 +3,6 @@ int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param) { -#ifdef __EMSCRIPTEN__ // XXX Emscripten web or Node workers doesn't support prioritizing threads - // no-op - return 0; -#else int r; sigset_t set; __block_app_sigs(&set); @@ -22,5 +18,4 @@ int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param UNLOCK(t->killlock); __restore_sigs(&set); return r; -#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_join.c b/system/lib/libc/musl/src/thread/pthread_join.c index a5d539b651754..17dae85d70861 100644 --- a/system/lib/libc/musl/src/thread/pthread_join.c +++ b/system/lib/libc/musl/src/thread/pthread_join.c @@ -9,69 +9,32 @@ weak_alias(dummy1, __tl_sync); static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at) { -#ifdef __EMSCRIPTEN__ - // Attempt to join a thread which does not point to a valid thread, or - // does not exist anymore. - if (!_emscripten_thread_is_valid(t)) return ESRCH; - // Thread is attempting to join to itself. Already detached threads are - // handled below by returning EINVAL instead. - // TODO: The detached check here is just to satisfy the - // `other.test_{proxy,main}_pthread_join_detach` tests. - if (t->detach_state != DT_DETACHED && __pthread_self() == t) return EDEADLK; -#endif int state, cs, r = 0; __pthread_testcancel(); __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); if (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0); while ((state = t->detach_state) && r != ETIMEDOUT && r != EINVAL) { -#ifdef __EMSCRIPTEN__ - // The thread is (already) detached and therefore not joinable. - // This also handle cases where the thread becomes detached - // *during* the join. - if (state >= DT_DETACHED) { - // Even though the man page says this is undefined behaviour we have - // several tests in the posixtest suite that depend on this. - r = EINVAL; - break; - } -#else if (state >= DT_DETACHED) a_crash(); -#endif r = __timedwait_cp(&t->detach_state, state, CLOCK_REALTIME, at, 1); } __pthread_setcancelstate(cs, 0); if (r == ETIMEDOUT || r == EINVAL) return r; __tl_sync(t); if (res) *res = t->result; -#ifdef __EMSCRIPTEN__ - // Thread was exited during this call, be sure to clean it up. - if (state == DT_EXITED) _emscripten_thread_cleanup(t); -#else // XXX Emscripten map_base unused if (t->map_base) __munmap(t->map_base, t->map_size); -#endif return 0; } int __pthread_join(pthread_t t, void **res) { -#ifdef __EMSCRIPTEN__ // XXX Emscripten check whether blocking is allowed. - emscripten_check_blocking_allowed(); -#endif return __pthread_timedjoin_np(t, res, 0); } static int __pthread_tryjoin_np(pthread_t t, void **res) { -#ifdef __EMSCRIPTEN__ // XXX Emscripten call __pthread_timedjoin_np directly to avoid additional check - return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_timedjoin_np(t, res, 0); -#else return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_join(t, res); -#endif } weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np); weak_alias(__pthread_timedjoin_np, pthread_timedjoin_np); weak_alias(__pthread_join, pthread_join); -#ifdef __EMSCRIPTEN__ // XXX Emscripten add an extra alias for LSan -weak_alias(__pthread_join, emscripten_builtin_pthread_join); -#endif diff --git a/system/lib/libc/musl/src/thread/pthread_key_create.c b/system/lib/libc/musl/src/thread/pthread_key_create.c index f45553919647a..39770c7a3c829 100644 --- a/system/lib/libc/musl/src/thread/pthread_key_create.c +++ b/system/lib/libc/musl/src/thread/pthread_key_create.c @@ -1,10 +1,6 @@ #include "pthread_impl.h" #include "fork_impl.h" -#ifdef __EMSCRIPTEN__ -#include -#endif - volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX; void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 }; diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_lock.c b/system/lib/libc/musl/src/thread/pthread_mutex_lock.c index 02269d366c858..638d4b8697d84 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_lock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_lock.c @@ -2,12 +2,9 @@ int __pthread_mutex_lock(pthread_mutex_t *m) { -#if !defined(__EMSCRIPTEN__) || defined(NDEBUG) - /* XXX EMSCRIPTEN always take the slow path in debug builds so we can trap rather than deadlock */ if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY)) return 0; -#endif return __pthread_mutex_timedlock(m, 0); } diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c index 232c9b321a8e2..9279fc54308ad 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c @@ -1,10 +1,5 @@ #include "pthread_impl.h" -#ifdef __EMSCRIPTEN__ -#include -#endif - -#ifndef __EMSCRIPTEN__ #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) @@ -57,16 +52,12 @@ static int pthread_mutex_timedlock_pi(pthread_mutex_t *restrict m, const struct while (e != ETIMEDOUT); return e; } -#endif int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at) { -#if !defined(__EMSCRIPTEN__) || defined(NDEBUG) - /* XXX EMSCRIPTEN always take the slow path in debug builds so we can trap rather than deadlock */ if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY)) return 0; -#endif int type = m->_m_type; int r, t, priv = (type & 128) ^ 128; @@ -74,9 +65,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec r = __pthread_mutex_trylock(m); if (r != EBUSY) return r; -#ifndef __EMSCRIPTEN__ if (type&8) return pthread_mutex_timedlock_pi(m, at); -#endif int spins = 100; while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); @@ -89,11 +78,6 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec if ((type&3) == PTHREAD_MUTEX_ERRORCHECK && own == __pthread_self()->tid) return EDEADLK; -#if defined(__EMSCRIPTEN__) && !defined(NDEBUG) - // Extra check for deadlock in debug builds, but only if we would block - // forever (at == NULL). - assert(at || own != __pthread_self()->tid && "pthread mutex deadlock detected"); -#endif a_inc(&m->_m_waiters); t = r | 0x80000000; diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c b/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c index 9a6719cf63b3a..a24e7c58ac390 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c @@ -6,7 +6,6 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) int type = m->_m_type; pthread_t self = __pthread_self(); int tid = self->tid; - volatile void *next; old = m->_m_lock; own = old & 0x3fffffff; @@ -28,9 +27,7 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) if (type & 128) { if (!self->robust_list.off) { self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next; -#ifndef __EMSCRIPTEN__ // XXX Emscripten does not have a concept of multiple processes or kernel space, so robust mutex lists don't need to register to kernel. __syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long)); -#endif } if (m->_m_waiters) tid |= 0x80000000; self->robust_list.pending = &m->_m_next; @@ -44,22 +41,14 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) } success: -#ifndef __EMSCRIPTEN__ if ((type&8) && m->_m_waiters) { int priv = (type & 128) ^ 128; __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); self->robust_list.pending = 0; return (type&4) ? ENOTRECOVERABLE : EBUSY; } -#endif -#if defined(__EMSCRIPTEN__) && !defined(NDEBUG) - // Under emscripten we can get here for normal mutexes too, but only in debug - // builds (where we track ownership purely for debug purposes). - if ((type&15) == PTHREAD_MUTEX_NORMAL) return 0; -#endif - - next = self->robust_list.head; + volatile void *next = self->robust_list.head; m->_m_next = next; m->_m_prev = &self->robust_list.head; if (next != &self->robust_list.head) *(volatile void *volatile *) @@ -77,11 +66,8 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) int __pthread_mutex_trylock(pthread_mutex_t *m) { -#if !defined(__EMSCRIPTEN__) || defined(NDEBUG) - /* XXX EMSCRIPTEN always take the slow path in debug builds so we can trap rather than deadlock */ if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL) return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY; -#endif return __pthread_mutex_trylock_owner(m); } diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c index af13bcfa12012..b66423e6c34f7 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c @@ -30,9 +30,6 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) if (next != &self->robust_list.head) *(volatile void *volatile *) ((char *)next - sizeof(void *)) = prev; } -#ifdef __EMSCRIPTEN__ - cont = a_swap(&m->_m_lock, new); -#else if (type&8) { if (old<0 || a_cas(&m->_m_lock, old, new)!=old) { if (new) a_store(&m->_m_waiters, -1); @@ -43,7 +40,6 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) } else { cont = a_swap(&m->_m_lock, new); } -#endif if (type != PTHREAD_MUTEX_NORMAL && !priv) { self->robust_list.pending = 0; __vm_unlock(); diff --git a/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c b/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c index bda16ebd5ba21..8b80c1ce9b14c 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c +++ b/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c @@ -11,7 +11,6 @@ int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol) a->__attr &= ~8; return 0; case PTHREAD_PRIO_INHERIT: -#ifndef __EMSCRIPTEN__ r = check_pi_result; if (r < 0) { volatile int lk = 0; @@ -21,7 +20,6 @@ int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol) if (r) return r; a->__attr |= 8; return 0; -#endif case PTHREAD_PRIO_PROTECT: return ENOTSUP; default: diff --git a/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c b/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c index e2f0d3cb859e8..100f6ff203f1b 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c +++ b/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c @@ -3,9 +3,6 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int pshared) { if (pshared > 1U) return EINVAL; -#ifdef __EMSCRIPTEN__ - if (pshared) return ENOTSUP; -#endif a->__attr &= ~128U; a->__attr |= pshared<<7; return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c b/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c index 7e181e2c0639e..30a9ac3bea559 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c +++ b/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c @@ -7,7 +7,6 @@ int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust) { if (robust > 1U) return EINVAL; if (robust) { -#ifndef __EMSCRIPTEN__ int r = check_robust_result; if (r < 0) { void *p; @@ -16,7 +15,6 @@ int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust) a_store(&check_robust_result, r); } if (r) return r; -#endif a->__attr |= 4; return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c index b147cb92ea9f5..d77706e6bc208 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c @@ -2,16 +2,11 @@ int __pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at) { -#ifdef __EMSCRIPTEN__ - /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. - /// If attempting to lock the write lock that we already own, error out. - if (rw->_rw_wr_owner == __pthread_self()->tid) return EDEADLK; -#endif int r, t; - + r = pthread_rwlock_trywrlock(rw); if (r != EBUSY) return r; - + int spins = 100; while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin(); @@ -24,11 +19,6 @@ int __pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct tim a_dec(&rw->_rw_waiters); if (r && r != EINTR) return r; } -#ifdef __EMSCRIPTEN__ - /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. - /// Mark this thread as the owner of this write lock. - rw->_rw_wr_owner = __pthread_self()->tid; -#endif return r; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c index e275bdaf1a1f1..64d9d3121a709 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c @@ -3,11 +3,6 @@ int __pthread_rwlock_trywrlock(pthread_rwlock_t *rw) { if (a_cas(&rw->_rw_lock, 0, 0x7fffffff)) return EBUSY; -#ifdef __EMSCRIPTEN__ - /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. - /// Mark this thread to own the write lock, to ignore multiple attempts to lock. - rw->_rw_wr_owner = __pthread_self()->tid; -#endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c index 7a55a085a0288..9ae27ad2b3a76 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c @@ -4,12 +4,6 @@ int __pthread_rwlock_unlock(pthread_rwlock_t *rw) { int val, cnt, waiters, new, priv = rw->_rw_shared^128; -#ifdef __EMSCRIPTEN__ - /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. - /// Mark this thread to not own the write lock anymore. - if (rw->_rw_wr_owner == __pthread_self()->tid) rw->_rw_wr_owner = 0; -#endif - do { val = rw->_rw_lock; cnt = val & 0x7fffffff; diff --git a/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c b/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c index 33f9466a60ddb..e7061973d6d6b 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c @@ -3,9 +3,6 @@ int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int pshared) { if (pshared > 1U) return EINVAL; -#ifdef __EMSCRIPTEN__ - if (pshared) return ENOTSUP; -#endif a->__attr[0] = pshared; return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_setconcurrency.c b/system/lib/libc/musl/src/thread/pthread_setconcurrency.c index deadf26ba9433..091abf98c86f3 100644 --- a/system/lib/libc/musl/src/thread/pthread_setconcurrency.c +++ b/system/lib/libc/musl/src/thread/pthread_setconcurrency.c @@ -3,9 +3,7 @@ int pthread_setconcurrency(int val) { -#ifndef __EMSCRIPTEN__ // XXX Emscripten marked as obsolescent in pthreads specification if (val < 0) return EINVAL; if (val > 0) return EAGAIN; -#endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_setschedparam.c b/system/lib/libc/musl/src/thread/pthread_setschedparam.c index 396aff5a33be0..76d4d45a3cdae 100644 --- a/system/lib/libc/musl/src/thread/pthread_setschedparam.c +++ b/system/lib/libc/musl/src/thread/pthread_setschedparam.c @@ -3,10 +3,6 @@ int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param) { -#ifdef __EMSCRIPTEN__ // XXX Emscripten web or Node workers doesn't support prioritizing threads - // no-op - return 0; -#else int r; sigset_t set; __block_app_sigs(&set); @@ -15,5 +11,4 @@ int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *par UNLOCK(t->killlock); __restore_sigs(&set); return r; -#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_setschedprio.c b/system/lib/libc/musl/src/thread/pthread_setschedprio.c index b8d53698683a7..fc2e13ddb3dbb 100644 --- a/system/lib/libc/musl/src/thread/pthread_setschedprio.c +++ b/system/lib/libc/musl/src/thread/pthread_setschedprio.c @@ -3,10 +3,6 @@ int pthread_setschedprio(pthread_t t, int prio) { -#ifdef __EMSCRIPTEN__ // XXX Emscripten web or Node workers doesn't support prioritizing threads - // no-op - return 0; -#else int r; sigset_t set; __block_app_sigs(&set); @@ -15,5 +11,4 @@ int pthread_setschedprio(pthread_t t, int prio) UNLOCK(t->killlock); __restore_sigs(&set); return r; -#endif } diff --git a/system/lib/libc/musl/src/thread/sem_init.c b/system/lib/libc/musl/src/thread/sem_init.c index f9b851778f2c8..55092434386f8 100644 --- a/system/lib/libc/musl/src/thread/sem_init.c +++ b/system/lib/libc/musl/src/thread/sem_init.c @@ -8,9 +8,6 @@ int sem_init(sem_t *sem, int pshared, unsigned value) errno = EINVAL; return -1; } -#ifdef __EMSCRIPTEN__ - if (pshared) return ENOTSUP; -#endif sem->__val[0] = value; sem->__val[1] = 0; sem->__val[2] = pshared ? 0 : 128; diff --git a/system/lib/libc/musl/src/thread/sem_timedwait.c b/system/lib/libc/musl/src/thread/sem_timedwait.c index 757795a9589dd..aa67376c2dcd8 100644 --- a/system/lib/libc/musl/src/thread/sem_timedwait.c +++ b/system/lib/libc/musl/src/thread/sem_timedwait.c @@ -25,9 +25,6 @@ int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at) r = __timedwait_cp(sem->__val, 0x80000000, CLOCK_REALTIME, at, priv); pthread_cleanup_pop(1); if (r) { -#ifdef __EMSCRIPTEN__ - if (r == ECANCELED) r = EINTR; -#endif errno = r; return -1; } diff --git a/system/lib/libc/musl/src/thread/thrd_create.c b/system/lib/libc/musl/src/thread/thrd_create.c index ca4efb661973b..76a683dbf87e7 100644 --- a/system/lib/libc/musl/src/thread/thrd_create.c +++ b/system/lib/libc/musl/src/thread/thrd_create.c @@ -1,15 +1,6 @@ #include "pthread_impl.h" #include -#ifdef __EMSCRIPTEN__ -// Fix for lsan. Since lsan wraps calls to the public `pthread_create` function -// if we call the internal __pthread_create function here to don't the wrapping -// See pthread_create wrapper in compiler-rt/lib/lsan/lsan_interceptors.cpp. -#define __pthread_create pthread_create -#else -int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict); -#endif - int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg); diff --git a/system/lib/libc/musl/src/thread/thrd_join.c b/system/lib/libc/musl/src/thread/thrd_join.c index abcdbc1aaeac2..0d5fd302d1810 100644 --- a/system/lib/libc/musl/src/thread/thrd_join.c +++ b/system/lib/libc/musl/src/thread/thrd_join.c @@ -5,11 +5,7 @@ int thrd_join(thrd_t t, int *res) { void *pthread_res; - int rtn = __pthread_join(t, &pthread_res); - // XXX Emscripten added handling of error case - if (rtn) { - return thrd_error; - } + __pthread_join(t, &pthread_res); if (res) *res = (int)(intptr_t)pthread_res; return thrd_success; } diff --git a/system/lib/libc/musl/src/thread/thrd_yield.c b/system/lib/libc/musl/src/thread/thrd_yield.c index d30d8843ac145..f7ad13219ce0d 100644 --- a/system/lib/libc/musl/src/thread/thrd_yield.c +++ b/system/lib/libc/musl/src/thread/thrd_yield.c @@ -3,7 +3,5 @@ void thrd_yield() { -#ifndef __EMSCRIPTEN__ __syscall(SYS_sched_yield); -#endif } diff --git a/system/lib/libc/musl/src/time/__map_file.c b/system/lib/libc/musl/src/time/__map_file.c index f4520b124c0b3..c2b29fe81b905 100644 --- a/system/lib/libc/musl/src/time/__map_file.c +++ b/system/lib/libc/musl/src/time/__map_file.c @@ -13,10 +13,6 @@ const char unsigned *__map_file(const char *pathname, size_t *size) map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); *size = st.st_size; } -#ifdef __EMSCRIPTEN__ - __wasi_fd_close(fd); -#else __syscall(SYS_close, fd); -#endif return map == MAP_FAILED ? 0 : map; } diff --git a/system/lib/libc/musl/src/time/__tz.c b/system/lib/libc/musl/src/time/__tz.c index 1aac321562e3a..c34b3eb755a54 100644 --- a/system/lib/libc/musl/src/time/__tz.c +++ b/system/lib/libc/musl/src/time/__tz.c @@ -9,19 +9,14 @@ #include "lock.h" #include "fork_impl.h" -#if defined(__EMSCRIPTEN__) && !defined(EMSCRIPTEN_STANDALONE_WASM) -#define USE_EXTERNAL_ZONEINFO -#include "emscripten_internal.h" -#endif - #define malloc __libc_malloc #define calloc undef #define realloc undef #define free undef -weak long __timezone = 0; -weak int __daylight = 0; -weak char *__tzname[2] = { 0, 0 }; +long __timezone = 0; +int __daylight = 0; +char *__tzname[2] = { 0, 0 }; weak_alias(__timezone, timezone); weak_alias(__daylight, daylight); @@ -29,26 +24,21 @@ weak_alias(__tzname, tzname); static char std_name[TZNAME_MAX+1]; static char dst_name[TZNAME_MAX+1]; -weak const char __utc[] = "UTC"; +const char __utc[] = "UTC"; static int dst_off; static int r0[5], r1[5]; -#ifndef USE_EXTERNAL_ZONEINFO static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end; static size_t map_size; -#endif static char old_tz_buf[32]; static char *old_tz = old_tz_buf; static size_t old_tz_size = sizeof old_tz_buf; static volatile int lock[1]; -#ifndef __EMSCRIPTEN__ volatile int *const __timezone_lockptr = lock; -#endif -#ifndef USE_EXTERNAL_ZONEINFO static int getint(const char **p) { unsigned x; @@ -132,17 +122,9 @@ static size_t zi_dotprod(const unsigned char *z, const unsigned char *v, size_t } return y; } -#endif static void do_tzset() { -#ifdef USE_EXTERNAL_ZONEINFO - if (!__tzname[0]) { - _tzset_js(&timezone, &daylight, std_name, dst_name); - __tzname[0] = std_name; - __tzname[1] = dst_name; - } -#else char buf[NAME_MAX+25], *pathname=buf+24; const char *try, *s, *p; const unsigned char *map = 0; @@ -273,10 +255,8 @@ static void do_tzset() if (*s == ',') s++, getrule(&s, r0); if (*s == ',') s++, getrule(&s, r1); -#endif } -#ifndef USE_EXTERNAL_ZONEINFO /* Search zoneinfo rules to find the one that applies to the given time, * and determine alternate opposite-DST-status rule that may be needed. */ @@ -436,7 +416,6 @@ void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppo *zonename = __tzname[1]; UNLOCK(lock); } -#endif static void __tzset() { @@ -447,16 +426,14 @@ static void __tzset() weak_alias(__tzset, tzset); -weak const char *__tm_to_tzname(const struct tm *tm) +const char *__tm_to_tzname(const struct tm *tm) { const void *p = tm->__tm_zone; LOCK(lock); do_tzset(); -#ifndef USE_EXTERNAL_ZONEINFO if (p != __utc && p != __tzname[0] && p != __tzname[1] && (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs)) p = ""; -#endif UNLOCK(lock); return p; } diff --git a/system/lib/libc/musl/src/time/clock_getres.c b/system/lib/libc/musl/src/time/clock_getres.c index b733fdc00f9d2..81c6703761d44 100644 --- a/system/lib/libc/musl/src/time/clock_getres.c +++ b/system/lib/libc/musl/src/time/clock_getres.c @@ -3,20 +3,6 @@ int clock_getres(clockid_t clk, struct timespec *ts) { -#ifdef __EMSCRIPTEN__ - // See https://github.com/bytecodealliance/wasmtime/issues/374 - if (clk > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk < 0) { - errno = EINVAL; - return -1; - } - __wasi_timestamp_t res; - __wasi_errno_t error = __wasi_clock_res_get(clk, &res); - if (error != __WASI_ERRNO_SUCCESS) { - return __wasi_syscall_ret(error); - } - *ts = __wasi_timestamp_to_timespec(res); - return 0; -#else #ifdef SYS_clock_getres_time64 /* On a 32-bit arch, use the old syscall if it exists. */ if (SYS_clock_getres != SYS_clock_getres_time64) { @@ -32,5 +18,4 @@ int clock_getres(clockid_t clk, struct timespec *ts) /* If reaching this point, it's a 64-bit arch or time64-only * 32-bit arch and we can get result directly into timespec. */ return syscall(SYS_clock_getres, clk, ts); -#endif } diff --git a/system/lib/libc/musl/src/time/clock_gettime.c b/system/lib/libc/musl/src/time/clock_gettime.c index 18926de8ce8f3..4d2ec22f38a00 100644 --- a/system/lib/libc/musl/src/time/clock_gettime.c +++ b/system/lib/libc/musl/src/time/clock_gettime.c @@ -56,24 +56,6 @@ static void *volatile vdso_func = (void *)cgt_init; #endif -#if __EMSCRIPTEN__ -_Static_assert(CLOCK_REALTIME == __WASI_CLOCKID_REALTIME, "monotonic clock must match"); -_Static_assert(CLOCK_MONOTONIC == __WASI_CLOCKID_MONOTONIC, "monotonic clock must match"); - -int __clock_gettime(clockid_t clk, struct timespec *ts) { - __wasi_timestamp_t timestamp; - // See https://github.com/bytecodealliance/wasmtime/issues/3714 - if (clk > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk < 0) { - errno = EINVAL; - return -1; - } - if (__wasi_syscall_ret(__wasi_clock_time_get(clk, 1, ×tamp))) { - return -1; - } - *ts = __wasi_timestamp_to_timespec(timestamp); - return 0; -} -#else // __EMSCRIPTEN__ int __clock_gettime(clockid_t clk, struct timespec *ts) { int r; @@ -128,6 +110,5 @@ int __clock_gettime(clockid_t clk, struct timespec *ts) return __syscall_ret(r); #endif } -#endif //__EMSCRIPTEN__ weak_alias(__clock_gettime, clock_gettime); diff --git a/system/lib/libc/musl/src/time/clock_nanosleep.c b/system/lib/libc/musl/src/time/clock_nanosleep.c index 7ad2aba1a0b7a..e195499cc0729 100644 --- a/system/lib/libc/musl/src/time/clock_nanosleep.c +++ b/system/lib/libc/musl/src/time/clock_nanosleep.c @@ -1,10 +1,6 @@ #include #include #include "syscall.h" -#if __EMSCRIPTEN__ -#include -#include -#endif #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) @@ -12,24 +8,6 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) { if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL; -#if __EMSCRIPTEN__ - if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999L || req->tv_sec < 0) { - return EINVAL; - } - struct timespec sleep_for = *req; - if (flags & TIMER_ABSTIME) { - struct timespec now; - clock_gettime(clk, &now); - if (now.tv_sec > req->tv_sec || (now.tv_sec == req->tv_sec && now.tv_nsec >= req->tv_nsec)) { - // The requested time has already passed - return 0; - } - sleep_for.tv_sec = req->tv_sec - now.tv_sec; - sleep_for.tv_nsec = req->tv_nsec - now.tv_nsec; - } - emscripten_thread_sleep(sleep_for.tv_sec * 1000.0 + sleep_for.tv_nsec / 1e6); - return 0; -#else #ifdef SYS_clock_nanosleep_time64 time_t s = req->tv_sec; long ns = req->tv_nsec; @@ -55,7 +33,6 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, stru return -__syscall_cp(SYS_nanosleep, req, rem); return -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem); #endif -#endif } weak_alias(__clock_nanosleep, clock_nanosleep); diff --git a/system/lib/libc/musl/src/time/clock_settime.c b/system/lib/libc/musl/src/time/clock_settime.c index ed0182fff664c..1004ed1528462 100644 --- a/system/lib/libc/musl/src/time/clock_settime.c +++ b/system/lib/libc/musl/src/time/clock_settime.c @@ -1,19 +1,11 @@ #include #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ -#include -#endif #define IS32BIT(x) !((x)+0x80000000ULL>>32) int clock_settime(clockid_t clk, const struct timespec *ts) { -#ifdef __EMSCRIPTEN__ - // JS and wasm VMs do not allow setting the time. - errno = EPERM; - return -1; -#else #ifdef SYS_clock_settime64 time_t s = ts->tv_sec; long ns = ts->tv_nsec; @@ -29,5 +21,4 @@ int clock_settime(clockid_t clk, const struct timespec *ts) #else return syscall(SYS_clock_settime, clk, ts); #endif -#endif } diff --git a/system/lib/libc/musl/src/time/localtime_r.c b/system/lib/libc/musl/src/time/localtime_r.c index ac0f37050a31f..1a15b314d0f12 100644 --- a/system/lib/libc/musl/src/time/localtime_r.c +++ b/system/lib/libc/musl/src/time/localtime_r.c @@ -4,18 +4,12 @@ struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm) { - /* Unlike other musl targets emscripten uses `int` for time_t rather than - * `int64`, so these checks don't apply (they rightly trigger - * `autological-constant-out-of-range-compare` warnings). - * TODO(sbc): Remove this if/when we switch to using int64 too. */ -#ifndef __EMSCRIPTEN__ /* Reject time_t values whose year would overflow int because * __secs_to_zone cannot safely handle them. */ if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) { errno = EOVERFLOW; return 0; } -#endif __secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone); if (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) { errno = EOVERFLOW; diff --git a/system/lib/libc/musl/src/time/strftime.c b/system/lib/libc/musl/src/time/strftime.c index 59d609ba92245..c40246dbb0fa3 100644 --- a/system/lib/libc/musl/src/time/strftime.c +++ b/system/lib/libc/musl/src/time/strftime.c @@ -226,13 +226,7 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st s[l] = 0; return l; } -#ifdef __EMSCRIPTEN__ - // Handle trailing % by outputting a % rather than returning 0. Ideally - // this 6 character change could be upstreamed into musl... - if (*f != '%' || !f[1]) { -#else if (*f != '%') { -#endif s[l++] = *f; continue; } diff --git a/system/lib/libc/musl/src/unistd/close.c b/system/lib/libc/musl/src/unistd/close.c index 5a453ff3324da..a2105f5060e23 100644 --- a/system/lib/libc/musl/src/unistd/close.c +++ b/system/lib/libc/musl/src/unistd/close.c @@ -13,13 +13,7 @@ weak_alias(dummy, __aio_close); int close(int fd) { fd = __aio_close(fd); -#ifdef __EMSCRIPTEN__ - int r = __wasi_fd_close(fd); - if (r == __WASI_ERRNO_INTR) r = __WASI_ERRNO_SUCCESS; - return __wasi_syscall_ret(r); -#else int r = __syscall_cp(SYS_close, fd); if (r == -EINTR) r = 0; return __syscall_ret(r); -#endif } diff --git a/system/lib/libc/musl/src/unistd/dup2.c b/system/lib/libc/musl/src/unistd/dup2.c index 793cfba1c7de8..8f43c6ddfe898 100644 --- a/system/lib/libc/musl/src/unistd/dup2.c +++ b/system/lib/libc/musl/src/unistd/dup2.c @@ -1,6 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#endif #include #include #include @@ -13,11 +10,7 @@ int dup2(int old, int new) while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); #else if (old==new) { -#ifdef __EMSCRIPTEN__ - r = __wasi_fd_is_valid(old) ? 0 : -EBADF; -#else r = __syscall(SYS_fcntl, old, F_GETFD); -#endif if (r >= 0) return old; } else { while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY); diff --git a/system/lib/libc/musl/src/unistd/faccessat.c b/system/lib/libc/musl/src/unistd/faccessat.c index bfc709d108472..43052dd70eeeb 100644 --- a/system/lib/libc/musl/src/unistd/faccessat.c +++ b/system/lib/libc/musl/src/unistd/faccessat.c @@ -4,7 +4,6 @@ #include "syscall.h" #include "pthread_impl.h" -#ifndef __EMSCRIPTEN__ struct ctx { int fd; const char *filename; @@ -23,13 +22,9 @@ static int checker(void *p) __syscall(SYS_write, c->p, &ret, sizeof ret); return 0; } -#endif int faccessat(int fd, const char *filename, int amode, int flag) { -#ifdef __EMSCRIPTEN__ - return syscall(SYS_faccessat, fd, filename, amode, flag); -#else if (flag) { int ret = __syscall(SYS_faccessat2, fd, filename, amode, flag); if (ret != -ENOSYS) return __syscall_ret(ret); @@ -63,5 +58,4 @@ int faccessat(int fd, const char *filename, int amode, int flag) __restore_sigs(&set); return __syscall_ret(ret); -#endif } diff --git a/system/lib/libc/musl/src/unistd/fchdir.c b/system/lib/libc/musl/src/unistd/fchdir.c index bcbd0fc9cc9cd..dee45ba68e642 100644 --- a/system/lib/libc/musl/src/unistd/fchdir.c +++ b/system/lib/libc/musl/src/unistd/fchdir.c @@ -1,6 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#endif #include #include #include @@ -9,13 +6,8 @@ int fchdir(int fd) { int ret = __syscall(SYS_fchdir, fd); -#if __EMSCRIPTEN__ - if (ret != -EBADF || !__wasi_fd_is_valid(fd)) - return __syscall_ret(ret); -#else if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); -#endif char buf[15+3*sizeof(int)]; __procfdname(buf, fd); diff --git a/system/lib/libc/musl/src/unistd/fchown.c b/system/lib/libc/musl/src/unistd/fchown.c index a328189505444..737b3672fcce5 100644 --- a/system/lib/libc/musl/src/unistd/fchown.c +++ b/system/lib/libc/musl/src/unistd/fchown.c @@ -1,6 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#endif #include #include #include @@ -9,11 +6,6 @@ int fchown(int fd, uid_t uid, gid_t gid) { int ret = __syscall(SYS_fchown, fd, uid, gid); -#if __EMSCRIPTEN__ - // We can't continue onwards to try the /proc/fd/NNN approach that musl does, - // as we don't support that much of POSIX. - return __syscall_ret(ret); -#else if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); @@ -24,5 +16,5 @@ int fchown(int fd, uid_t uid, gid_t gid) #else return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0); #endif -#endif // EMSCRIPTEN + } diff --git a/system/lib/libc/musl/src/unistd/fsync.c b/system/lib/libc/musl/src/unistd/fsync.c index 2b26be534e96c..7a1c80b5de0d8 100644 --- a/system/lib/libc/musl/src/unistd/fsync.c +++ b/system/lib/libc/musl/src/unistd/fsync.c @@ -3,9 +3,5 @@ int fsync(int fd) { -#if __EMSCRIPTEN__ - return __wasi_syscall_ret(__wasi_fd_sync(fd)); -#else return syscall_cp(SYS_fsync, fd); -#endif } diff --git a/system/lib/libc/musl/src/unistd/isatty.c b/system/lib/libc/musl/src/unistd/isatty.c index 1e41a6edbd1aa..75a9c186a9418 100644 --- a/system/lib/libc/musl/src/unistd/isatty.c +++ b/system/lib/libc/musl/src/unistd/isatty.c @@ -1,6 +1,3 @@ -#ifdef __EMSCRIPTEN__ -#include -#endif #include #include #include @@ -8,27 +5,9 @@ int isatty(int fd) { -#ifdef __EMSCRIPTEN__ - __wasi_fdstat_t statbuf; - int err = __wasi_fd_fdstat_get(fd, &statbuf); - if (err != 0) { - errno = err; - return 0; - } - - // All character devices are terminals (other things a Linux system would - // assume is a character device, like the mouse, we have special APIs for). - if (statbuf.fs_filetype != __WASI_FILETYPE_CHARACTER_DEVICE) { - errno = __WASI_ERRNO_NOTTY; - return 0; - } - - return 1; -#else struct winsize wsz; unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz); if (r == 0) return 1; if (errno != EBADF) errno = ENOTTY; return 0; -#endif } diff --git a/system/lib/libc/musl/src/unistd/lseek.c b/system/lib/libc/musl/src/unistd/lseek.c index 199e784c01d74..f5b66682abc46 100644 --- a/system/lib/libc/musl/src/unistd/lseek.c +++ b/system/lib/libc/musl/src/unistd/lseek.c @@ -3,17 +3,12 @@ off_t __lseek(int fd, off_t offset, int whence) { -#ifdef __EMSCRIPTEN__ - off_t result; - return __wasi_syscall_ret(__wasi_fd_seek(fd, offset, whence, &result)) ? -1 : result; -#else #ifdef SYS__llseek off_t result; return syscall(SYS__llseek, fd, offset>>32, offset, &result, whence) ? -1 : result; #else return syscall(SYS_lseek, fd, offset, whence); #endif -#endif // __EMSCRIPTEN__ } weak_alias(__lseek, lseek); diff --git a/system/lib/libc/musl/src/unistd/pipe2.c b/system/lib/libc/musl/src/unistd/pipe2.c index f215000b31c4d..a096990b1503d 100644 --- a/system/lib/libc/musl/src/unistd/pipe2.c +++ b/system/lib/libc/musl/src/unistd/pipe2.c @@ -11,12 +11,10 @@ int pipe2(int fd[2], int flag) if (flag & ~(O_CLOEXEC|O_NONBLOCK)) return __syscall_ret(-EINVAL); ret = pipe(fd); if (ret) return ret; -#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (flag & O_CLOEXEC) { __syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC); __syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC); } -#endif if (flag & O_NONBLOCK) { __syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK); __syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK); diff --git a/system/lib/libc/musl/src/unistd/pread.c b/system/lib/libc/musl/src/unistd/pread.c index a2361a0473b51..b03fb0ad94076 100644 --- a/system/lib/libc/musl/src/unistd/pread.c +++ b/system/lib/libc/musl/src/unistd/pread.c @@ -3,17 +3,5 @@ ssize_t pread(int fd, void *buf, size_t size, off_t ofs) { -#if __EMSCRIPTEN__ - __wasi_iovec_t iov = { - .buf = buf, - .buf_len = size - }; - size_t num; - if (__wasi_syscall_ret(__wasi_fd_pread(fd, &iov, 1, ofs, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs)); -#endif } diff --git a/system/lib/libc/musl/src/unistd/preadv.c b/system/lib/libc/musl/src/unistd/preadv.c index fa6b78c101b3f..890ab403f9dbd 100644 --- a/system/lib/libc/musl/src/unistd/preadv.c +++ b/system/lib/libc/musl/src/unistd/preadv.c @@ -5,14 +5,6 @@ ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs) { -#if __EMSCRIPTEN__ - size_t num; - if (__wasi_syscall_ret(__wasi_fd_pread(fd, (struct __wasi_iovec_t*)iov, count, ofs, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_preadv, fd, iov, count, (long)(ofs), (long)(ofs>>32)); -#endif } diff --git a/system/lib/libc/musl/src/unistd/pwrite.c b/system/lib/libc/musl/src/unistd/pwrite.c index 3573ab3902f82..869b69f03b88e 100644 --- a/system/lib/libc/musl/src/unistd/pwrite.c +++ b/system/lib/libc/musl/src/unistd/pwrite.c @@ -3,17 +3,5 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { -#if __EMSCRIPTEN__ - __wasi_ciovec_t iov = { - .buf = buf, - .buf_len = size - }; - size_t num; - if (__wasi_syscall_ret(__wasi_fd_pwrite(fd, &iov, 1, ofs, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs)); -#endif } diff --git a/system/lib/libc/musl/src/unistd/pwritev.c b/system/lib/libc/musl/src/unistd/pwritev.c index bb44236c51ef7..becf9debfc3c8 100644 --- a/system/lib/libc/musl/src/unistd/pwritev.c +++ b/system/lib/libc/musl/src/unistd/pwritev.c @@ -5,14 +5,6 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { -#if __EMSCRIPTEN__ - size_t num; - if (__wasi_syscall_ret(__wasi_fd_pwrite(fd, (struct __wasi_ciovec_t*)iov, count, ofs, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_pwritev, fd, iov, count, (long)(ofs), (long)(ofs>>32)); -#endif } diff --git a/system/lib/libc/musl/src/unistd/read.c b/system/lib/libc/musl/src/unistd/read.c index f079439c9d302..f3589c05c3e3b 100644 --- a/system/lib/libc/musl/src/unistd/read.c +++ b/system/lib/libc/musl/src/unistd/read.c @@ -3,17 +3,5 @@ ssize_t read(int fd, void *buf, size_t count) { -#if __EMSCRIPTEN__ - __wasi_iovec_t iov = { - .buf = buf, - .buf_len = count - }; - size_t num; - if (__wasi_syscall_ret(__wasi_fd_read(fd, &iov, 1, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_read, fd, buf, count); -#endif } diff --git a/system/lib/libc/musl/src/unistd/readv.c b/system/lib/libc/musl/src/unistd/readv.c index bb0760da6e147..91e6de8167793 100644 --- a/system/lib/libc/musl/src/unistd/readv.c +++ b/system/lib/libc/musl/src/unistd/readv.c @@ -3,13 +3,5 @@ ssize_t readv(int fd, const struct iovec *iov, int count) { -#if __EMSCRIPTEN__ - size_t num; - if (__wasi_syscall_ret(__wasi_fd_read(fd, (struct __wasi_iovec_t*)iov, count, &num))) { - num = -1; - } - return num; -#else return syscall_cp(SYS_readv, fd, iov, count); -#endif } diff --git a/system/lib/libc/musl/src/unistd/setxid.c b/system/lib/libc/musl/src/unistd/setxid.c index ab707276a32cd..a629ed4b46e57 100644 --- a/system/lib/libc/musl/src/unistd/setxid.c +++ b/system/lib/libc/musl/src/unistd/setxid.c @@ -3,12 +3,6 @@ #include "syscall.h" #include "libc.h" -#ifdef __EMSCRIPTEN__ -int __setxid_emscripten() { - errno = EPERM; // we don't allow dynamic syscalls, and don't need to support these anyhow - return -1; -} -#else struct ctx { int id, eid, sid; int nr, ret; @@ -27,7 +21,7 @@ static void do_setxid(void *p) __block_all_sigs(0); __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL); } - c->err = ret; + c->ret = ret; } int __setxid(int nr, int id, int eid, int sid) @@ -38,4 +32,3 @@ int __setxid(int nr, int id, int eid, int sid) __synccall(do_setxid, &c); return __syscall_ret(c.ret > 0 ? -EAGAIN : c.ret); } -#endif diff --git a/system/lib/libc/musl/src/unistd/write.c b/system/lib/libc/musl/src/unistd/write.c index 53742cd4fd972..8fd5bc5c261ce 100644 --- a/system/lib/libc/musl/src/unistd/write.c +++ b/system/lib/libc/musl/src/unistd/write.c @@ -3,17 +3,5 @@ ssize_t write(int fd, const void *buf, size_t count) { -#if __EMSCRIPTEN__ - __wasi_ciovec_t iov = { - .buf = buf, - .buf_len = count - }; - size_t num; - if (__wasi_syscall_ret(__wasi_fd_write(fd, &iov, 1, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_write, fd, buf, count); -#endif } diff --git a/system/lib/libc/musl/src/unistd/writev.c b/system/lib/libc/musl/src/unistd/writev.c index 443d14f35d1be..5a46c951af57c 100644 --- a/system/lib/libc/musl/src/unistd/writev.c +++ b/system/lib/libc/musl/src/unistd/writev.c @@ -1,18 +1,7 @@ #include #include "syscall.h" -#if __EMSCRIPTEN__ -#include -#endif ssize_t writev(int fd, const struct iovec *iov, int count) { -#if __EMSCRIPTEN__ - size_t num; - if (__wasi_syscall_ret(__wasi_fd_write(fd, (struct __wasi_ciovec_t*)iov, count, &num))) { - return -1; - } - return num; -#else return syscall_cp(SYS_writev, fd, iov, count); -#endif } diff --git a/system/lib/libc/musl/tools/mkalltypes.sed b/system/lib/libc/musl/tools/mkalltypes.sed deleted file mode 100644 index fa15efc35f64e..0000000000000 --- a/system/lib/libc/musl/tools/mkalltypes.sed +++ /dev/null @@ -1,15 +0,0 @@ -/^TYPEDEF/s/TYPEDEF \(.*\) \([^ ]*\);$/#if defined(__NEED_\2) \&\& !defined(__DEFINED_\2)\ -typedef \1 \2;\ -#define __DEFINED_\2\ -#endif\ -/ -/^STRUCT/s/STRUCT * \([^ ]*\) \(.*\);$/#if defined(__NEED_struct_\1) \&\& !defined(__DEFINED_struct_\1)\ -struct \1 \2;\ -#define __DEFINED_struct_\1\ -#endif\ -/ -/^UNION/s/UNION * \([^ ]*\) \(.*\);$/#if defined(__NEED_union_\1) \&\& !defined(__DEFINED_union_\1)\ -union \1 \2;\ -#define __DEFINED_union_\1\ -#endif\ -/ From aabc8b294616217502b76a85c8b32d031de85e40 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 11:32:12 +0200 Subject: [PATCH 02/17] musl: update arch ignore list In preparation for the next commit. --- system/lib/update_musl.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/system/lib/update_musl.py b/system/lib/update_musl.py index a13debc2dfb76..262717c6fd3f1 100755 --- a/system/lib/update_musl.py +++ b/system/lib/update_musl.py @@ -31,9 +31,11 @@ # Parts of src we don't build 'malloc', # Arch-specific code we don't use - 'arm', 'x32', 'sh', 'i386', 'x86_64', 'aarch64', 'riscv64', - 's390x', 'mips', 'mips64', 'mipsn32', 'powerpc', 'powerpc64', - 'm68k', 'microblaze', 'or1k') + 'aarch64', 'arm', 'i386', 'loongarch64', 'm68k', + 'microblaze', 'mips', 'mips64', 'mipsn32', 'or1k', + 'powerpc', 'powerpc64', 'riscv32', 'riscv64', 's390x', + 'sh', 'x32', 'x86_64' +) exclude_files = ( 'aio.h', 'sendfile.h', From fa6d187c2808f0e3907afd1673fd2f564c57d983 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 11:38:05 +0200 Subject: [PATCH 03/17] Update musl to v1.2.6 This is an automatic change generated with: ``` ./system/lib/update_musl.py ~/Downloads/musl-1.2.6 ``` --- system/lib/libc/musl/COPYRIGHT | 4 +- system/lib/libc/musl/Makefile | 2 +- system/lib/libc/musl/VERSION | 2 +- system/lib/libc/musl/WHATSNEW | 53 +++++++++++++++ system/lib/libc/musl/arch/generic/bits/reg.h | 0 system/lib/libc/musl/arch/generic/bits/stat.h | 18 +++++ .../lib/libc/musl/arch/generic/bits/stdint.h | 29 ++++++++ system/lib/libc/musl/include/dirent.h | 18 ++++- system/lib/libc/musl/include/elf.h | 31 +++++++++ system/lib/libc/musl/include/netinet/in.h | 3 +- system/lib/libc/musl/include/sched.h | 17 +++-- system/lib/libc/musl/include/shadow.h | 1 - system/lib/libc/musl/include/stdio.h | 7 ++ system/lib/libc/musl/include/sys/mman.h | 4 ++ system/lib/libc/musl/include/sys/reg.h | 9 +++ system/lib/libc/musl/include/sys/stat.h | 27 +++++++- system/lib/libc/musl/include/sys/uio.h | 1 + system/lib/libc/musl/include/sys/user.h | 9 +++ system/lib/libc/musl/include/syslog.h | 2 +- system/lib/libc/musl/include/unistd.h | 8 ++- system/lib/libc/musl/ldso/dlstart.c | 2 +- system/lib/libc/musl/ldso/dynlink.c | 22 +++---- system/lib/libc/musl/src/complex/cacosh.c | 2 +- system/lib/libc/musl/src/complex/catan.c | 25 +------ system/lib/libc/musl/src/complex/catanf.c | 28 +------- system/lib/libc/musl/src/complex/catanl.c | 24 +------ system/lib/libc/musl/src/conf/sysconf.c | 9 ++- .../lib/libc/musl/src/dirent/posix_getdents.c | 11 ++++ system/lib/libc/musl/src/errno/__strerror.h | 2 + system/lib/libc/musl/src/exit/atexit.c | 12 ++++ system/lib/libc/musl/src/exit/exit.c | 14 ++++ system/lib/libc/musl/src/internal/atomic.h | 2 +- system/lib/libc/musl/src/internal/syscall.h | 11 ++++ system/lib/libc/musl/src/internal/vdso.c | 28 +++++++- system/lib/libc/musl/src/internal/version.h | 2 +- .../lib/libc/musl/src/legacy/getusershell.c | 6 +- system/lib/libc/musl/src/linux/renameat2.c | 11 ++++ system/lib/libc/musl/src/linux/statx.c | 4 +- .../musl/src/locale/bind_textdomain_codeset.c | 6 +- system/lib/libc/musl/src/locale/codepages.h | 11 ++++ system/lib/libc/musl/src/locale/iconv.c | 15 ++++- system/lib/libc/musl/src/math/fma.c | 2 +- system/lib/libc/musl/src/math/powl.c | 8 --- system/lib/libc/musl/src/misc/initgroups.c | 26 ++++++-- system/lib/libc/musl/src/misc/mntent.c | 12 +++- .../lib/libc/musl/src/multibyte/mbsnrtowcs.c | 6 +- system/lib/libc/musl/src/network/getifaddrs.c | 4 +- system/lib/libc/musl/src/network/inet_ntop.c | 7 +- system/lib/libc/musl/src/network/res_msend.c | 2 +- system/lib/libc/musl/src/passwd/getgr_a.c | 12 +++- system/lib/libc/musl/src/signal/sigaltstack.c | 4 +- system/lib/libc/musl/src/signal/siglongjmp.c | 5 ++ system/lib/libc/musl/src/signal/sigpause.c | 2 +- .../lib/libc/musl/src/stdio/__stdio_write.c | 5 ++ system/lib/libc/musl/src/stdio/vfprintf.c | 36 +++++----- system/lib/libc/musl/src/stdlib/qsort.c | 2 +- system/lib/libc/musl/src/string/strcasestr.c | 1 + .../lib/libc/musl/src/termios/cfgetospeed.c | 2 +- .../lib/libc/musl/src/termios/cfsetospeed.c | 10 ++- system/lib/libc/musl/src/termios/cfsetspeed.c | 11 ++++ system/lib/libc/musl/src/thread/sem_post.c | 2 +- system/lib/libc/musl/src/time/__tz.c | 1 - system/lib/libc/musl/src/time/__utc.c | 3 + system/lib/libc/musl/src/time/strptime.c | 66 ++++++++++++++++++- system/lib/libc/musl/src/time/timer_create.c | 29 ++++++-- system/lib/libc/musl/src/unistd/isatty.c | 6 +- system/lib/libc/musl/src/unistd/pause.c | 6 +- system/lib/libc/musl/src/unistd/pwrite.c | 11 ++++ system/lib/libc/musl/src/unistd/pwritev.c | 10 ++- 69 files changed, 596 insertions(+), 187 deletions(-) create mode 100644 system/lib/libc/musl/arch/generic/bits/reg.h create mode 100644 system/lib/libc/musl/arch/generic/bits/stat.h create mode 100644 system/lib/libc/musl/arch/generic/bits/stdint.h create mode 100644 system/lib/libc/musl/src/dirent/posix_getdents.c create mode 100644 system/lib/libc/musl/src/linux/renameat2.c create mode 100644 system/lib/libc/musl/src/termios/cfsetspeed.c create mode 100644 system/lib/libc/musl/src/time/__utc.c diff --git a/system/lib/libc/musl/COPYRIGHT b/system/lib/libc/musl/COPYRIGHT index c1628e9ac84f9..2f15edc7a1793 100644 --- a/system/lib/libc/musl/COPYRIGHT +++ b/system/lib/libc/musl/COPYRIGHT @@ -74,6 +74,7 @@ Kylie McClain Leah Neukirchen Luca Barbato Luka Perkov +Lynn Ochs M Farkas-Dyck (Strake) Mahesh Bodapati Markus Wichmann @@ -103,7 +104,6 @@ Stefan O'Rear Szabolcs Nagy Timo Teräs Trutz Behn -Valentin Ochs Will Dietz William Haddon William Pitcock @@ -143,7 +143,7 @@ domain. The code also comes with a fallback permissive license for use in jurisdictions that may not recognize the public domain. The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 -Valentin Ochs and is licensed under an MIT-style license. +Lynn Ochs and is licensed under an MIT-style license. The x86_64 port was written by Nicholas J. Kain and is licensed under the standard MIT terms. diff --git a/system/lib/libc/musl/Makefile b/system/lib/libc/musl/Makefile index e8cc443675efc..3ad88b359a7a4 100644 --- a/system/lib/libc/musl/Makefile +++ b/system/lib/libc/musl/Makefile @@ -109,7 +109,7 @@ obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version obj/crt/rcrt1.o obj/ldso/dlstart.lo obj/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h -obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h +obj/crt/crt1.o obj/crt/Scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h obj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.c diff --git a/system/lib/libc/musl/VERSION b/system/lib/libc/musl/VERSION index c813fe116c9f9..3c43790f5d820 100644 --- a/system/lib/libc/musl/VERSION +++ b/system/lib/libc/musl/VERSION @@ -1 +1 @@ -1.2.5 +1.2.6 diff --git a/system/lib/libc/musl/WHATSNEW b/system/lib/libc/musl/WHATSNEW index 7bd9072801db3..bb2cd9bd8a005 100644 --- a/system/lib/libc/musl/WHATSNEW +++ b/system/lib/libc/musl/WHATSNEW @@ -2438,3 +2438,56 @@ arch-specific bugs fixed: - riscv64 icache flush operation was non-functional - sh sigsetjmp failed to properly restore call-saved register r8 on return - sh dlsym RTLD_NEXT did not identify calling module correctly + + + +1.2.6 release notes + +new features: +- posix_getdents interface (new in POSIX-2024) +- renameat2 interface (linux extension) +- iconv support for CP858 +- vdso clock_gettime for riscv{32,64}, powerpc{,64}, and s390x +- loongarch64 TLSDESC support +- exposed __getauxval for compiler runtime use detecting cpu features + +compatibility: +- initgroups no longer artificially limits number of supplementary groups +- getusershell now skips blank lines and comments +- exit is now explicitly thread-safe (possible future requirement) +- atexit now fails rather than deadlocking if called from late dtor +- strerror now has error strings for EUCLEAN and ENAVAIL +- isatty no longer collapses errors to ENOTTY +- sched.h namespace pollution with _GNU_SOURCE is reduced +- hasmntopt now matches only whole options, not arbitrary substrings +- shadow.h no longer declares an unimplemented sgetspent interface +- vdso with missing sysv hash table (only gnu hash) is now supported + +conformance: +- pwrite now handles O_APPEND correctly, reports error if it can't +- mbnrtowcs now conforms to new POSIX-2024 requirement for partial character +- iconv GBK now properly includes euro symbol +- strptime now accepts conversion specifiers added in POSIX-2024 +- inet_ntop IPv6 "zero compression" now conforms to RFC 5952 + +bugs fixed: +- iconv euc-kr decoder could do oob writes on invalid inputs (CVE-2025-26519) +- iconv shift_jis decoder could produce wrong outputs for some invalid inputs +- printf did not honor hex float precision correctly in some cases +- lost or delayed wakes in sem_post under race condition +- termios input speed handling was wrong +- strcasestr failed to match zero-length needle +- fma handled corner case with negative zero wrongly +- syslog LOG_MAKEPRI macro was incorrect +- timer_create is no longer affected by known pthread_barrier bugs +- sysconf(_SC_MINSIGSTKSZ) computed min size incorrectly +- statx emulation left some fields uninitialized +- mntent wrongly included final newline in parsed field output +- SIGEV_THREAD timers could abort process if SIGTIMER became unblocked +- bind_textdomain_codeset returned wrong value + +arch-specific bugs fixed: +- early dynamic linker handled page size wrong on dynamic pagesize archs +- arm and aarch64 crti/n files had wrong alignment +- m68k POLLWRNORM and POLLWRBAND values were incorrect +- x32 mq ABI was mismatched diff --git a/system/lib/libc/musl/arch/generic/bits/reg.h b/system/lib/libc/musl/arch/generic/bits/reg.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/system/lib/libc/musl/arch/generic/bits/stat.h b/system/lib/libc/musl/arch/generic/bits/stat.h new file mode 100644 index 0000000000000..f6d9e864068db --- /dev/null +++ b/system/lib/libc/musl/arch/generic/bits/stat.h @@ -0,0 +1,18 @@ +struct stat { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + unsigned long long __pad; + off_t st_size; + blksize_t st_blksize; + int __pad2; + blkcnt_t st_blocks; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned __unused[2]; +}; diff --git a/system/lib/libc/musl/arch/generic/bits/stdint.h b/system/lib/libc/musl/arch/generic/bits/stdint.h new file mode 100644 index 0000000000000..8648918746aed --- /dev/null +++ b/system/lib/libc/musl/arch/generic/bits/stdint.h @@ -0,0 +1,29 @@ +typedef int32_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef uint32_t uint_fast16_t; +typedef uint32_t uint_fast32_t; + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN + +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX + +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#if __LONG_MAX == 0x7fffffffL +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX +#define SIZE_MAX UINT32_MAX +#else +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX +#define SIZE_MAX UINT64_MAX +#endif diff --git a/system/lib/libc/musl/include/dirent.h b/system/lib/libc/musl/include/dirent.h index 2d8fffb23f001..7fa60e0672171 100644 --- a/system/lib/libc/musl/include/dirent.h +++ b/system/lib/libc/musl/include/dirent.h @@ -9,14 +9,23 @@ extern "C" { #define __NEED_ino_t #define __NEED_off_t -#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) #define __NEED_size_t -#endif +#define __NEED_ssize_t #include #include +typedef unsigned short reclen_t; + +struct posix_dent { + ino_t d_ino; + off_t d_off; + reclen_t d_reclen; + unsigned char d_type; + char d_name[]; +}; + typedef struct __dirstream DIR; #define d_fileno d_ino @@ -29,6 +38,8 @@ int readdir_r(DIR *__restrict, struct dirent *__restrict, struct dire void rewinddir(DIR *); int dirfd(DIR *); +ssize_t posix_getdents(int, void *, size_t, int); + int alphasort(const struct dirent **, const struct dirent **); int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)); @@ -37,7 +48,6 @@ void seekdir(DIR *, long); long telldir(DIR *); #endif -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #define DT_UNKNOWN 0 #define DT_FIFO 1 #define DT_CHR 2 @@ -47,6 +57,8 @@ long telldir(DIR *); #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #define IFTODT(x) ((x)>>12 & 017) #define DTTOIF(x) ((x)<<12) int getdents(int, struct dirent *, size_t); diff --git a/system/lib/libc/musl/include/elf.h b/system/lib/libc/musl/include/elf.h index 3d5e13e4b6e53..2555b90610b0d 100644 --- a/system/lib/libc/musl/include/elf.h +++ b/system/lib/libc/musl/include/elf.h @@ -712,6 +712,8 @@ typedef struct { #define NT_LOONGARCH_LSX 0xa02 #define NT_LOONGARCH_LASX 0xa03 #define NT_LOONGARCH_LBT 0xa04 +#define NT_LOONGARCH_HW_BREAK 0xa05 +#define NT_LOONGARCH_HW_WATCH 0xa06 @@ -1040,6 +1042,8 @@ typedef struct { #define AT_RANDOM 25 #define AT_HWCAP2 26 +#define AT_HWCAP3 29 +#define AT_HWCAP4 30 #define AT_EXECFN 31 @@ -3329,6 +3333,7 @@ enum #define R_LARCH_TLS_TPREL32 10 #define R_LARCH_TLS_TPREL64 11 #define R_LARCH_IRELATIVE 12 +#define R_LARCH_TLS_DESC64 14 #define R_LARCH_MARK_LA 20 #define R_LARCH_MARK_PCREL 21 #define R_LARCH_SOP_PUSH_PCREL 22 @@ -3405,6 +3410,32 @@ enum #define R_LARCH_TLS_GD_HI20 98 #define R_LARCH_32_PCREL 99 #define R_LARCH_RELAX 100 +#define R_LARCH_DELETE 101 +#define R_LARCH_ALIGN 102 +#define R_LARCH_PCREL20_S2 103 +#define R_LARCH_CFA 104 +#define R_LARCH_ADD6 105 +#define R_LARCH_SUB6 106 +#define R_LARCH_ADD_ULEB128 107 +#define R_LARCH_SUB_ULEB128 108 +#define R_LARCH_64_PCREL 109 +#define R_LARCH_CALL36 110 +#define R_LARCH_TLS_DESC_PC_HI20 111 +#define R_LARCH_TLS_DESC_PC_LO12 112 +#define R_LARCH_TLS_DESC64_PC_LO20 113 +#define R_LARCH_TLS_DESC64_PC_HI12 114 +#define R_LARCH_TLS_DESC_HI20 115 +#define R_LARCH_TLS_DESC_LO12 116 +#define R_LARCH_TLS_DESC64_LO20 117 +#define R_LARCH_TLS_DESC64_HI12 118 +#define R_LARCH_TLS_DESC_LD 119 +#define R_LARCH_TLS_DESC_CALL 120 +#define R_LARCH_TLS_LE_HI20_R 121 +#define R_LARCH_TLS_LE_ADD_R 122 +#define R_LARCH_TLS_LE_LO12_R 123 +#define R_LARCH_TLS_LD_PCREL20_S2 124 +#define R_LARCH_TLS_GD_PCREL20_S2 125 +#define R_LARCH_TLS_DESC_PCREL20_S2 126 #ifdef __cplusplus } diff --git a/system/lib/libc/musl/include/netinet/in.h b/system/lib/libc/musl/include/netinet/in.h index fb628b61a9c40..60bbaa75b1728 100644 --- a/system/lib/libc/musl/include/netinet/in.h +++ b/system/lib/libc/musl/include/netinet/in.h @@ -132,7 +132,8 @@ uint16_t ntohs(uint16_t); #define IN6_IS_ADDR_V4COMPAT(a) \ (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \ - ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1) + ((uint32_t *) (a))[2] == 0 && \ + !IN6_IS_ADDR_UNSPECIFIED(a) && !IN6_IS_ADDR_LOOPBACK(a)) #define IN6_IS_ADDR_MC_NODELOCAL(a) \ (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1)) diff --git a/system/lib/libc/musl/include/sched.h b/system/lib/libc/musl/include/sched.h index 204c34f5679f3..8c3b53f0fe7a5 100644 --- a/system/lib/libc/musl/include/sched.h +++ b/system/lib/libc/musl/include/sched.h @@ -78,11 +78,10 @@ int clone (int (*)(void *), void *, int, void *, ...); int unshare(int); int setns(int, int); -void *memcpy(void *__restrict, const void *__restrict, size_t); -int memcmp(const void *, const void *, size_t); -void *memset (void *, int, size_t); -void *calloc(size_t, size_t); -void free(void *); +int (memcmp)(const void *, const void *, size_t); +void *(memset)(void *, int, size_t); +void *(calloc)(size_t, size_t); +void (free)(void *); typedef struct cpu_set_t { unsigned long __bits[128/sizeof(long)]; } cpu_set_t; int __sched_cpucount(size_t, const cpu_set_t *); @@ -116,13 +115,13 @@ __CPU_op_func_S(XOR, ^) #define CPU_XOR_S(a,b,c,d) __CPU_XOR_S(a,b,c,d) #define CPU_COUNT_S(size,set) __sched_cpucount(size,set) -#define CPU_ZERO_S(size,set) memset(set,0,size) -#define CPU_EQUAL_S(size,set1,set2) (!memcmp(set1,set2,size)) +#define CPU_ZERO_S(size,set) (memset)(set,0,size) +#define CPU_EQUAL_S(size,set1,set2) (!(memcmp)(set1,set2,size)) #define CPU_ALLOC_SIZE(n) (sizeof(long) * ( (n)/(8*sizeof(long)) \ + ((n)%(8*sizeof(long)) + 8*sizeof(long)-1)/(8*sizeof(long)) ) ) -#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n))) -#define CPU_FREE(set) free(set) +#define CPU_ALLOC(n) ((cpu_set_t *)(calloc)(1,CPU_ALLOC_SIZE(n))) +#define CPU_FREE(set) (free)(set) #define CPU_SETSIZE 1024 diff --git a/system/lib/libc/musl/include/shadow.h b/system/lib/libc/musl/include/shadow.h index 2b1be413f3643..a9d6940f17f62 100644 --- a/system/lib/libc/musl/include/shadow.h +++ b/system/lib/libc/musl/include/shadow.h @@ -28,7 +28,6 @@ void setspent(void); void endspent(void); struct spwd *getspent(void); struct spwd *fgetspent(FILE *); -struct spwd *sgetspent(const char *); int putspent(const struct spwd *, FILE *); struct spwd *getspnam(const char *); diff --git a/system/lib/libc/musl/include/stdio.h b/system/lib/libc/musl/include/stdio.h index cb858618512d8..4ea4c17077a3b 100644 --- a/system/lib/libc/musl/include/stdio.h +++ b/system/lib/libc/musl/include/stdio.h @@ -158,6 +158,13 @@ char *ctermid(char *); #define L_ctermid 20 #endif +#if defined(_GNU_SOURCE) +#define RENAME_NOREPLACE (1 << 0) +#define RENAME_EXCHANGE (1 << 1) +#define RENAME_WHITEOUT (1 << 2) + +int renameat2(int, const char *, int, const char *, unsigned); +#endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) diff --git a/system/lib/libc/musl/include/sys/mman.h b/system/lib/libc/musl/include/sys/mman.h index 3d5d0f9c23383..aa2c48177a9e4 100644 --- a/system/lib/libc/musl/include/sys/mman.h +++ b/system/lib/libc/musl/include/sys/mman.h @@ -95,6 +95,10 @@ extern "C" { #define MADV_KEEPONFORK 19 #define MADV_COLD 20 #define MADV_PAGEOUT 21 +#define MADV_POPULATE_READ 22 +#define MADV_POPULATE_WRITE 23 +#define MADV_DONTNEED_LOCKED 24 +#define MADV_COLLAPSE 25 #define MADV_HWPOISON 100 #define MADV_SOFT_OFFLINE 101 #endif diff --git a/system/lib/libc/musl/include/sys/reg.h b/system/lib/libc/musl/include/sys/reg.h index b47452d003ec6..0272e1370f238 100644 --- a/system/lib/libc/musl/include/sys/reg.h +++ b/system/lib/libc/musl/include/sys/reg.h @@ -4,6 +4,15 @@ #include #include +#include + +#undef __WORDSIZE +#if __LONG_MAX == 0x7fffffffL +#define __WORDSIZE 32 +#else +#define __WORDSIZE 64 +#endif + #include #endif diff --git a/system/lib/libc/musl/include/sys/stat.h b/system/lib/libc/musl/include/sys/stat.h index 6690192d19565..4f7dc2b1082c2 100644 --- a/system/lib/libc/musl/include/sys/stat.h +++ b/system/lib/libc/musl/include/sys/stat.h @@ -120,6 +120,22 @@ int lchmod(const char *, mode_t); #define STATX_BASIC_STATS 0x7ffU #define STATX_BTIME 0x800U #define STATX_ALL 0xfffU +#define STATX_MNT_ID 0x1000U +#define STATX_DIOALIGN 0x2000U +#define STATX_MNT_ID_UNIQUE 0x4000U +#define STATX_SUBVOL 0x8000U +#define STATX_WRITE_ATOMIC 0x10000U + +#define STATX_ATTR_COMPRESSED 0x4 +#define STATX_ATTR_IMMUTABLE 0x10 +#define STATX_ATTR_APPEND 0x20 +#define STATX_ATTR_NODUMP 0x40 +#define STATX_ATTR_ENCRYPTED 0x800 +#define STATX_ATTR_AUTOMOUNT 0x1000 +#define STATX_ATTR_MOUNT_ROOT 0x2000 +#define STATX_ATTR_VERITY 0x100000 +#define STATX_ATTR_DAX 0x200000 +#define STATX_ATTR_WRITE_ATOMIC 0x400000 struct statx_timestamp { int64_t tv_sec; @@ -147,7 +163,16 @@ struct statx { uint32_t stx_rdev_minor; uint32_t stx_dev_major; uint32_t stx_dev_minor; - uint64_t __pad1[14]; + uint64_t stx_mnt_id; + uint32_t stx_dio_mem_align; + uint32_t stx_dio_offset_align; + uint64_t stx_subvol; + uint32_t stx_atomic_write_unit_min; + uint32_t stx_atomic_write_unit_max; + uint32_t stx_atomic_write_segments_max; + uint32_t __pad1[1]; + uint64_t __pad2[9]; + }; int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict); diff --git a/system/lib/libc/musl/include/sys/uio.h b/system/lib/libc/musl/include/sys/uio.h index 8b5e3de79ce84..5e99c7fa24455 100644 --- a/system/lib/libc/musl/include/sys/uio.h +++ b/system/lib/libc/musl/include/sys/uio.h @@ -46,6 +46,7 @@ ssize_t pwritev2 (int, const struct iovec *, int, off_t, int); #define RWF_SYNC 0x00000004 #define RWF_NOWAIT 0x00000008 #define RWF_APPEND 0x00000010 +#define RWF_NOAPPEND 0x00000020 #endif #ifdef __cplusplus diff --git a/system/lib/libc/musl/include/sys/user.h b/system/lib/libc/musl/include/sys/user.h index 96a03400900b6..511caba389b43 100644 --- a/system/lib/libc/musl/include/sys/user.h +++ b/system/lib/libc/musl/include/sys/user.h @@ -8,6 +8,15 @@ extern "C" { #include #include +#include + +#undef __WORDSIZE +#if __LONG_MAX == 0x7fffffffL +#define __WORDSIZE 32 +#else +#define __WORDSIZE 64 +#endif + #include #ifdef __cplusplus diff --git a/system/lib/libc/musl/include/syslog.h b/system/lib/libc/musl/include/syslog.h index 5b4d2964e780e..57599e076e925 100644 --- a/system/lib/libc/musl/include/syslog.h +++ b/system/lib/libc/musl/include/syslog.h @@ -18,7 +18,7 @@ extern "C" { #define LOG_PRIMASK 7 #define LOG_PRI(p) ((p)&LOG_PRIMASK) -#define LOG_MAKEPRI(f, p) (((f)<<3)|(p)) +#define LOG_MAKEPRI(f, p) ((f)|(p)) #define LOG_MASK(p) (1<<(p)) #define LOG_UPTO(p) ((1<<((p)+1))-1) diff --git a/system/lib/libc/musl/include/unistd.h b/system/lib/libc/musl/include/unistd.h index 5bc7f7982f5ed..42b0e82bd9e7b 100644 --- a/system/lib/libc/musl/include/unistd.h +++ b/system/lib/libc/musl/include/unistd.h @@ -257,7 +257,13 @@ pid_t gettid(void); #define _POSIX2_C_BIND _POSIX_VERSION -#include +#if __LONG_MAX == 0x7fffffffL +#define _POSIX_V6_ILP32_OFFBIG 1 +#define _POSIX_V7_ILP32_OFFBIG 1 +#else +#define _POSIX_V6_LP64_OFF64 1 +#define _POSIX_V7_LP64_OFF64 1 +#endif diff --git a/system/lib/libc/musl/ldso/dlstart.c b/system/lib/libc/musl/ldso/dlstart.c index 259f5e18eecf8..4aac42bc23572 100644 --- a/system/lib/libc/musl/ldso/dlstart.c +++ b/system/lib/libc/musl/ldso/dlstart.c @@ -45,7 +45,7 @@ hidden void _dlstart_c(size_t *sp, size_t *dynv) /* If dynv is null, the entry point was started from loader * that is not fdpic-aware. We can assume normal fixed- * displacement ELF loading was performed, but when ldso was - * run as a command, finding the Ehdr is a heursitic: we + * run as a command, finding the Ehdr is a heuristic: we * have to assume Phdrs start in the first 4k of the file. */ base = aux[AT_BASE]; if (!base) base = aux[AT_PHDR] & -4096; diff --git a/system/lib/libc/musl/ldso/dynlink.c b/system/lib/libc/musl/ldso/dynlink.c index 324aa85919f0f..715948f4f8b3e 100644 --- a/system/lib/libc/musl/ldso/dynlink.c +++ b/system/lib/libc/musl/ldso/dynlink.c @@ -21,15 +21,17 @@ #include #include "pthread_impl.h" #include "fork_impl.h" +#include "libc.h" #include "dynlink.h" static size_t ldso_page_size; -#ifndef PAGE_SIZE +/* libc.h may have defined a macro for dynamic PAGE_SIZE already, but + * PAGESIZE is only defined if it's constant for the arch. */ +#ifndef PAGESIZE +#undef PAGE_SIZE #define PAGE_SIZE ldso_page_size #endif -#include "libc.h" - #define malloc __libc_malloc #define calloc __libc_calloc #define realloc __libc_realloc @@ -360,19 +362,14 @@ static struct symdef get_lfs64(const char *name) "pwritev\0readdir\0scandir\0sendfile\0setrlimit\0" "stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0" "__fxstat\0__fxstatat\0__lxstat\0__xstat\0"; - size_t l; - char buf[16]; - for (l=0; name[l]; l++) { - if (l >= sizeof buf) goto nomatch; - buf[l] = name[l]; - } if (!strcmp(name, "readdir64_r")) return find_sym(&ldso, "readdir_r", 1); - if (l<2 || name[l-2]!='6' || name[l-1]!='4') + size_t l = strnlen(name, 18); + if (l<2 || name[l-2]!='6' || name[l-1]!='4' || name[l]) goto nomatch; - buf[l-=2] = 0; for (p=lfs64_list; *p; p++) { - if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1); + if (!strncmp(name, p, l-2) && !p[l-2]) + return find_sym(&ldso, p, 1); while (*p) p++; } nomatch: @@ -619,6 +616,7 @@ static void reclaim_gaps(struct dso *dso) for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) { if (ph->p_type!=PT_LOAD) continue; if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue; + if (ph->p_memsz == 0) continue; reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr); reclaim(dso, ph->p_vaddr+ph->p_memsz, ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE); diff --git a/system/lib/libc/musl/src/complex/cacosh.c b/system/lib/libc/musl/src/complex/cacosh.c index 76127f75f4bb1..55b857cefea37 100644 --- a/system/lib/libc/musl/src/complex/cacosh.c +++ b/system/lib/libc/musl/src/complex/cacosh.c @@ -1,6 +1,6 @@ #include "complex_impl.h" -/* acosh(z) = i acos(z) */ +/* acosh(z) = ±i acos(z) */ double complex cacosh(double complex z) { diff --git a/system/lib/libc/musl/src/complex/catan.c b/system/lib/libc/musl/src/complex/catan.c index ccc2fb539af79..b4fe552a786ae 100644 --- a/system/lib/libc/musl/src/complex/catan.c +++ b/system/lib/libc/musl/src/complex/catan.c @@ -60,29 +60,6 @@ #include "complex_impl.h" -#define MAXNUM 1.0e308 - -static const double DP1 = 3.14159265160560607910E0; -static const double DP2 = 1.98418714791870343106E-9; -static const double DP3 = 1.14423774522196636802E-17; - -static double _redupi(double x) -{ - double t; - long i; - - t = x/M_PI; - if (t >= 0.0) - t += 0.5; - else - t -= 0.5; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - double complex catan(double complex z) { double complex w; @@ -95,7 +72,7 @@ double complex catan(double complex z) a = 1.0 - x2 - (y * y); t = 0.5 * atan2(2.0 * x, a); - w = _redupi(t); + w = t; t = y - 1.0; a = x2 + (t * t); diff --git a/system/lib/libc/musl/src/complex/catanf.c b/system/lib/libc/musl/src/complex/catanf.c index 1d569f2dacf99..faaa907a27e21 100644 --- a/system/lib/libc/musl/src/complex/catanf.c +++ b/system/lib/libc/musl/src/complex/catanf.c @@ -55,32 +55,6 @@ #include "complex_impl.h" -#define MAXNUMF 1.0e38F - -static const double DP1 = 3.140625; -static const double DP2 = 9.67502593994140625E-4; -static const double DP3 = 1.509957990978376432E-7; - -static const float float_pi = M_PI; - -static float _redupif(float xx) -{ - float x, t; - long i; - - x = xx; - t = x/float_pi; - if (t >= 0.0f) - t += 0.5f; - else - t -= 0.5f; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - float complex catanf(float complex z) { float complex w; @@ -93,7 +67,7 @@ float complex catanf(float complex z) a = 1.0f - x2 - (y * y); t = 0.5f * atan2f(2.0f * x, a); - w = _redupif(t); + w = t; t = y - 1.0f; a = x2 + (t * t); diff --git a/system/lib/libc/musl/src/complex/catanl.c b/system/lib/libc/musl/src/complex/catanl.c index e62526c00672b..cd2d2b0032723 100644 --- a/system/lib/libc/musl/src/complex/catanl.c +++ b/system/lib/libc/musl/src/complex/catanl.c @@ -67,28 +67,6 @@ long double complex catanl(long double complex z) return catan(z); } #else -static const long double PIL = 3.141592653589793238462643383279502884197169L; -static const long double DP1 = 3.14159265358979323829596852490908531763125L; -static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L; -static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L; - -static long double redupil(long double x) -{ - long double t; - long i; - - t = x / PIL; - if (t >= 0.0L) - t += 0.5L; - else - t -= 0.5L; - - i = t; /* the multiple */ - t = i; - t = ((x - t * DP1) - t * DP2) - t * DP3; - return t; -} - long double complex catanl(long double complex z) { long double complex w; @@ -101,7 +79,7 @@ long double complex catanl(long double complex z) a = 1.0L - x2 - (y * y); t = atan2l(2.0L * x, a) * 0.5L; - w = redupil(t); + w = t; t = y - 1.0L; a = x2 + (t * t); diff --git a/system/lib/libc/musl/src/conf/sysconf.c b/system/lib/libc/musl/src/conf/sysconf.c index 60d3e745350dc..8dd5c725031dd 100644 --- a/system/lib/libc/musl/src/conf/sysconf.c +++ b/system/lib/libc/musl/src/conf/sysconf.c @@ -220,8 +220,13 @@ long sysconf(int name) return (mem > LONG_MAX) ? LONG_MAX : mem; case JT_MINSIGSTKSZ & 255: case JT_SIGSTKSZ & 255: ; - long val = __getauxval(AT_MINSIGSTKSZ); - if (val < MINSIGSTKSZ) val = MINSIGSTKSZ; + /* Value from auxv/kernel is only sigfame size. Clamp it + * to at least 1k below arch's traditional MINSIGSTKSZ, + * then add 1k of working space for signal handler. */ + unsigned long sigframe_sz = __getauxval(AT_MINSIGSTKSZ); + if (sigframe_sz < MINSIGSTKSZ - 1024) + sigframe_sz = MINSIGSTKSZ - 1024; + unsigned val = sigframe_sz + 1024; if (values[name] == JT_SIGSTKSZ) val += SIGSTKSZ - MINSIGSTKSZ; return val; diff --git a/system/lib/libc/musl/src/dirent/posix_getdents.c b/system/lib/libc/musl/src/dirent/posix_getdents.c new file mode 100644 index 0000000000000..26c16ac6b8e94 --- /dev/null +++ b/system/lib/libc/musl/src/dirent/posix_getdents.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include "syscall.h" + +ssize_t posix_getdents(int fd, void *buf, size_t len, int flags) +{ + if (flags) return __syscall_ret(-EOPNOTSUPP); + if (len>INT_MAX) len = INT_MAX; + return syscall(SYS_getdents, fd, buf, len); +} diff --git a/system/lib/libc/musl/src/errno/__strerror.h b/system/lib/libc/musl/src/errno/__strerror.h index 14925907b55d3..0398b5b6d5404 100644 --- a/system/lib/libc/musl/src/errno/__strerror.h +++ b/system/lib/libc/musl/src/errno/__strerror.h @@ -97,6 +97,8 @@ E(ESHUTDOWN, "Cannot send after socket shutdown") E(EALREADY, "Operation already in progress") E(EINPROGRESS, "Operation in progress") E(ESTALE, "Stale file handle") +E(EUCLEAN, "Data consistency error") +E(ENAVAIL, "Resource not available") E(EREMOTEIO, "Remote I/O error") E(EDQUOT, "Quota exceeded") E(ENOMEDIUM, "No medium found") diff --git a/system/lib/libc/musl/src/exit/atexit.c b/system/lib/libc/musl/src/exit/atexit.c index 854e9fddbe559..92c91c9de8c9b 100644 --- a/system/lib/libc/musl/src/exit/atexit.c +++ b/system/lib/libc/musl/src/exit/atexit.c @@ -19,6 +19,7 @@ static struct fl void *a[COUNT]; } builtin, *head; +static int finished_atexit; static int slot; static volatile int lock[1]; volatile int *const __atexit_lockptr = lock; @@ -34,6 +35,10 @@ void __funcs_on_exit() func(arg); LOCK(lock); } + /* Unlock to prevent deadlock if a global dtor + * attempts to call atexit. */ + finished_atexit = 1; + UNLOCK(lock); } void __cxa_finalize(void *dso) @@ -44,6 +49,13 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso) { LOCK(lock); + /* Prevent dtors from registering further atexit + * handlers that would never be run. */ + if (finished_atexit) { + UNLOCK(lock); + return -1; + } + /* Defer initialization of head so it can be in BSS */ if (!head) head = &builtin; diff --git a/system/lib/libc/musl/src/exit/exit.c b/system/lib/libc/musl/src/exit/exit.c index a6869b37594ea..17b33cc61716c 100644 --- a/system/lib/libc/musl/src/exit/exit.c +++ b/system/lib/libc/musl/src/exit/exit.c @@ -1,6 +1,9 @@ #include #include #include "libc.h" +#include "pthread_impl.h" +#include "atomic.h" +#include "syscall.h" static void dummy() { @@ -26,6 +29,17 @@ weak_alias(libc_exit_fini, __libc_exit_fini); _Noreturn void exit(int code) { + /* Handle potentially concurrent or recursive calls to exit, + * whose behaviors have traditionally been undefined by the + * standards. Using a custom lock here avoids pulling in lock + * machinery and lets us trap recursive calls while supporting + * multiple threads contending to be the one to exit(). */ + static volatile int exit_lock[1]; + int tid = __pthread_self()->tid; + int prev = a_cas(exit_lock, 0, tid); + if (prev == tid) a_crash(); + else if (prev) for (;;) __sys_pause(); + __funcs_on_exit(); __libc_exit_fini(); __stdio_exit(); diff --git a/system/lib/libc/musl/src/internal/atomic.h b/system/lib/libc/musl/src/internal/atomic.h index 96c1552d6eda6..8f71c8cdf75c0 100644 --- a/system/lib/libc/musl/src/internal/atomic.h +++ b/system/lib/libc/musl/src/internal/atomic.h @@ -194,7 +194,7 @@ static inline void a_store(volatile int *p, int v) #ifndef a_barrier #define a_barrier a_barrier -static void a_barrier() +static inline void a_barrier() { volatile int tmp = 0; a_cas(&tmp, 0, 0); diff --git a/system/lib/libc/musl/src/internal/syscall.h b/system/lib/libc/musl/src/internal/syscall.h index 33d981f986506..2d8a5c134db0f 100644 --- a/system/lib/libc/musl/src/internal/syscall.h +++ b/system/lib/libc/musl/src/internal/syscall.h @@ -391,6 +391,17 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) #define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) +#ifdef SYS_pause +#define __sys_pause() __syscall(SYS_pause) +#define __sys_pause_cp() __syscall_cp(SYS_pause) +#else +#define __sys_pause() __syscall(SYS_ppoll, 0, 0, 0, 0) +#define __sys_pause_cp() __syscall_cp(SYS_ppoll, 0, 0, 0, 0) +#endif + +#define sys_pause() __syscall_ret(__sys_pause()) +#define sys_pause_cp() __syscall_ret(__sys_pause_cp()) + #ifdef SYS_wait4 #define __sys_wait4(a,b,c,d) __syscall(SYS_wait4,a,b,c,d) #define __sys_wait4_cp(a,b,c,d) __syscall_cp(SYS_wait4,a,b,c,d) diff --git a/system/lib/libc/musl/src/internal/vdso.c b/system/lib/libc/musl/src/internal/vdso.c index d46d32281e649..2b6e1ae2893d1 100644 --- a/system/lib/libc/musl/src/internal/vdso.c +++ b/system/lib/libc/musl/src/internal/vdso.c @@ -40,6 +40,24 @@ static int checkver(Verdef *def, int vsym, const char *vername, char *strings) #define OK_TYPES (1< nsym) + nsym = buckets[i]; + } + if (nsym) { + hashval = buckets + gh[0] + (nsym - gh[1]); + do nsym++; + while (!(*hashval++ & 1)); + } + return nsym; +} + + void *__vdsosym(const char *vername, const char *name) { size_t i; @@ -60,6 +78,7 @@ void *__vdsosym(const char *vername, const char *name) char *strings = 0; Sym *syms = 0; Elf_Symndx *hashtab = 0; + uint32_t *ghashtab = 0; uint16_t *versym = 0; Verdef *verdef = 0; @@ -69,15 +88,20 @@ void *__vdsosym(const char *vername, const char *name) case DT_STRTAB: strings = p; break; case DT_SYMTAB: syms = p; break; case DT_HASH: hashtab = p; break; + case DT_GNU_HASH: ghashtab = p; break; case DT_VERSYM: versym = p; break; case DT_VERDEF: verdef = p; break; } } - if (!strings || !syms || !hashtab) return 0; + if (!strings || !syms) return 0; if (!verdef) versym = 0; + size_t nsym = 0; + + if (hashtab) nsym = hashtab[1]; + else if (ghashtab) nsym = count_syms_gnu(ghashtab); - for (i=0; i>4) & OK_BINDS)) continue; if (!syms[i].st_shndx) continue; diff --git a/system/lib/libc/musl/src/internal/version.h b/system/lib/libc/musl/src/internal/version.h index a324baa3e16fb..b426e1a4def13 100644 --- a/system/lib/libc/musl/src/internal/version.h +++ b/system/lib/libc/musl/src/internal/version.h @@ -1 +1 @@ -#define VERSION "1.2.5" +#define VERSION "1.2.6" diff --git a/system/lib/libc/musl/src/legacy/getusershell.c b/system/lib/libc/musl/src/legacy/getusershell.c index 5fecdec2e4419..1c5d98ec0e6cf 100644 --- a/system/lib/libc/musl/src/legacy/getusershell.c +++ b/system/lib/libc/musl/src/legacy/getusershell.c @@ -25,8 +25,10 @@ char *getusershell(void) ssize_t l; if (!f) setusershell(); if (!f) return 0; - l = getline(&line, &linesize, f); - if (l <= 0) return 0; + do { + l = getline(&line, &linesize, f); + if (l <= 0) return 0; + } while (line[0] == '#' || line[0] == '\n'); if (line[l-1]=='\n') line[l-1]=0; return line; } diff --git a/system/lib/libc/musl/src/linux/renameat2.c b/system/lib/libc/musl/src/linux/renameat2.c new file mode 100644 index 0000000000000..b806038890d26 --- /dev/null +++ b/system/lib/libc/musl/src/linux/renameat2.c @@ -0,0 +1,11 @@ +#define _GNU_SOURCE +#include +#include "syscall.h" + +int renameat2(int oldfd, const char *old, int newfd, const char *new, unsigned flags) +{ +#ifdef SYS_renameat + if (!flags) return syscall(SYS_renameat, oldfd, old, newfd, new); +#endif + return syscall(SYS_renameat2, oldfd, old, newfd, new, flags); +} diff --git a/system/lib/libc/musl/src/linux/statx.c b/system/lib/libc/musl/src/linux/statx.c index 4616bff4aadfc..4fb96e4bd1ffd 100644 --- a/system/lib/libc/musl/src/linux/statx.c +++ b/system/lib/libc/musl/src/linux/statx.c @@ -19,8 +19,11 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct ret = fstatat(dirfd, path, &st, flags); if (ret) return ret; + *stx = (struct statx){0}; stx->stx_dev_major = major(st.st_dev); stx->stx_dev_minor = minor(st.st_dev); + stx->stx_rdev_major = major(st.st_rdev); + stx->stx_rdev_minor = minor(st.st_rdev); stx->stx_ino = st.st_ino; stx->stx_mode = st.st_mode; stx->stx_nlink = st.st_nlink; @@ -35,7 +38,6 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec; stx->stx_ctime.tv_sec = st.st_ctim.tv_sec; stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec; - stx->stx_btime = (struct statx_timestamp){.tv_sec=0, .tv_nsec=0}; stx->stx_mask = STATX_BASIC_STATS; return 0; diff --git a/system/lib/libc/musl/src/locale/bind_textdomain_codeset.c b/system/lib/libc/musl/src/locale/bind_textdomain_codeset.c index 5ebfd5e8a818f..240e83edffeff 100644 --- a/system/lib/libc/musl/src/locale/bind_textdomain_codeset.c +++ b/system/lib/libc/musl/src/locale/bind_textdomain_codeset.c @@ -5,7 +5,9 @@ char *bind_textdomain_codeset(const char *domainname, const char *codeset) { - if (codeset && strcasecmp(codeset, "UTF-8")) + if (codeset && strcasecmp(codeset, "UTF-8")) { errno = EINVAL; - return NULL; + return 0; + } + return "UTF-8"; } diff --git a/system/lib/libc/musl/src/locale/codepages.h b/system/lib/libc/musl/src/locale/codepages.h index 4e236ef3abee8..a254f0f58781b 100644 --- a/system/lib/libc/musl/src/locale/codepages.h +++ b/system/lib/libc/musl/src/locale/codepages.h @@ -286,6 +286,17 @@ "\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55" "\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50" +"cp858\0" +"\0\40" +"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61" +"\311\230\143\14\75\366\310\263\117\76\377\130\303\15\76\243\140\163\15\135" +"\341\264\63\217\76\361\104\243\212\56\277\270\302\112\57\274\204\262\312\56" +"\140\207\55\66\315\72\7\43\14\60\251\104\375\163\321\113\213\122\212\315" +"\67\363\274\163\316\63\367\74\316\60\110\13\175\65\325\116\373\254\65\51" +"\360\100\243\314\62\310\220\334\214\63\317\340\134\163\327\134\233\302\314\326" +"\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55" +"\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50" + "cp866\0" "\0\40" "\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172" diff --git a/system/lib/libc/musl/src/locale/iconv.c b/system/lib/libc/musl/src/locale/iconv.c index 175def1c63f1a..52178950d470c 100644 --- a/system/lib/libc/musl/src/locale/iconv.c +++ b/system/lib/libc/musl/src/locale/iconv.c @@ -52,7 +52,7 @@ static const unsigned char charmaps[] = "shiftjis\0sjis\0cp932\0\0\321" "iso2022jp\0\0\322" "gb18030\0\0\330" -"gbk\0\0\331" +"gbk\0cp936\0windows936\0\0\331" "gb2312\0\0\332" "big5\0bigfive\0cp950\0big5hkscs\0\0\340" "euckr\0ksc5601\0ksx1001\0cp949\0\0\350" @@ -339,7 +339,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri } else if (d-159 <= 252-159) { c++; d -= 159; + } else { + goto ilseq; } + if (c>=84) goto ilseq; c = jis0208[c][d]; if (!c) goto ilseq; break; @@ -403,6 +406,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (c < 128) break; if (c < 0xa1) goto ilseq; case GBK: + if (c == 128) { + c = 0x20ac; + break; + } case GB18030: if (c < 128) break; c -= 0x81; @@ -495,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (c >= 93 || d >= 94) { c += (0xa1-0x81); d += 0xa1; - if (c >= 93 || c>=0xc6-0x81 && d>0x52) + if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52) goto ilseq; if (d-'A'<26) d = d-'A'; else if (d-'a'<26) d = d-'a'+26; @@ -538,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri if (*outb < k) goto toobig; memcpy(*out, tmp, k); } else k = wctomb_utf8(*out, c); + /* This failure condition should be unreachable, but + * is included to prevent decoder bugs from translating + * into advancement outside the output buffer range. */ + if (k>4) goto ilseq; *out += k; *outb -= k; break; diff --git a/system/lib/libc/musl/src/math/fma.c b/system/lib/libc/musl/src/math/fma.c index 0c6f90c9cfd14..adfadca8c256f 100644 --- a/system/lib/libc/musl/src/math/fma.c +++ b/system/lib/libc/musl/src/math/fma.c @@ -53,7 +53,7 @@ double fma(double x, double y, double z) return x*y + z; if (nz.e >= ZEROINFNAN) { if (nz.e > ZEROINFNAN) /* z==0 */ - return x*y + z; + return x*y; return z; } diff --git a/system/lib/libc/musl/src/math/powl.c b/system/lib/libc/musl/src/math/powl.c index 6f64ea71182d8..9eb2216205e17 100644 --- a/system/lib/libc/musl/src/math/powl.c +++ b/system/lib/libc/musl/src/math/powl.c @@ -57,14 +57,6 @@ * IEEE 0,8700 60000 6.5e-18 1.0e-18 * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM INFINITY - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * */ #include "libm.h" diff --git a/system/lib/libc/musl/src/misc/initgroups.c b/system/lib/libc/musl/src/misc/initgroups.c index 922a958142b0a..101f5c7b0363a 100644 --- a/system/lib/libc/musl/src/misc/initgroups.c +++ b/system/lib/libc/musl/src/misc/initgroups.c @@ -1,11 +1,29 @@ #define _GNU_SOURCE #include #include +#include int initgroups(const char *user, gid_t gid) { - gid_t groups[NGROUPS_MAX]; - int count = NGROUPS_MAX; - if (getgrouplist(user, gid, groups, &count) < 0) return -1; - return setgroups(count, groups); + gid_t buf[32], *groups = buf; + int count = sizeof buf / sizeof *buf, prev_count = count; + while (getgrouplist(user, gid, groups, &count) < 0) { + if (groups != buf) free(groups); + + /* Return if failure isn't buffer size */ + if (count <= prev_count) + return -1; + + /* Always increase by at least 50% to limit to + * logarithmically many retries on TOCTOU races. */ + if (count < prev_count + (prev_count>>1)) + count = prev_count + (prev_count>>1); + + groups = calloc(count, sizeof *groups); + if (!groups) return -1; + prev_count = count; + } + int ret = setgroups(count, groups); + if (groups != buf) free(groups); + return ret; } diff --git a/system/lib/libc/musl/src/misc/mntent.c b/system/lib/libc/musl/src/misc/mntent.c index 78bf0cd0f52fa..76f9c16271685 100644 --- a/system/lib/libc/musl/src/misc/mntent.c +++ b/system/lib/libc/musl/src/misc/mntent.c @@ -81,7 +81,7 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle len = strlen(linebuf); if (len > INT_MAX) continue; for (i = 0; i < sizeof n / sizeof *n; i++) n[i] = len; - sscanf(linebuf, " %n%*[^ \t]%n %n%*[^ \t]%n %n%*[^ \t]%n %n%*[^ \t]%n %d %d", + sscanf(linebuf, " %n%*[^ \t\n]%n %n%*[^ \t\n]%n %n%*[^ \t\n]%n %n%*[^ \t\n]%n %d %d", n, n+1, n+2, n+3, n+4, n+5, n+6, n+7, &mnt->mnt_freq, &mnt->mnt_passno); } while (linebuf[n[0]] == '#' || n[1]==len); @@ -115,5 +115,13 @@ int addmntent(FILE *f, const struct mntent *mnt) char *hasmntopt(const struct mntent *mnt, const char *opt) { - return strstr(mnt->mnt_opts, opt); + size_t l = strlen(opt); + char *p = mnt->mnt_opts; + for (;;) { + if (!strncmp(p, opt, l) && (!p[l] || p[l]==',' || p[l]=='=')) + return p; + p = strchr(p, ','); + if (!p) return 0; + p++; + } } diff --git a/system/lib/libc/musl/src/multibyte/mbsnrtowcs.c b/system/lib/libc/musl/src/multibyte/mbsnrtowcs.c index 931192e2d83c4..47cbdc0044967 100644 --- a/system/lib/libc/musl/src/multibyte/mbsnrtowcs.c +++ b/system/lib/libc/musl/src/multibyte/mbsnrtowcs.c @@ -2,11 +2,13 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st) { + static unsigned internal_state; size_t l, cnt=0, n2; wchar_t *ws, wbuf[256]; const char *s = *src; const char *tmp_s; + if (!st) st = (void *)&internal_state; if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf; else ws = wcs; @@ -41,8 +43,8 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si s = 0; break; } - /* have to roll back partial character */ - *(unsigned *)st = 0; + s += n; + n -= n; break; } s += l; n -= l; diff --git a/system/lib/libc/musl/src/network/getifaddrs.c b/system/lib/libc/musl/src/network/getifaddrs.c index 74df4d6c6a211..55039bd89682e 100644 --- a/system/lib/libc/musl/src/network/getifaddrs.c +++ b/system/lib/libc/musl/src/network/getifaddrs.c @@ -13,8 +13,8 @@ /* getifaddrs() reports hardware addresses with PF_PACKET that implies * struct sockaddr_ll. But e.g. Infiniband socket address length is - * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct - * to extend ssl_addr - callers should be able to still use it. */ + * longer than sockaddr_ll.sll_addr[8] can hold. Use this hack struct + * to extend sll_addr - callers should be able to still use it. */ struct sockaddr_ll_hack { unsigned short sll_family, sll_protocol; int sll_ifindex; diff --git a/system/lib/libc/musl/src/network/inet_ntop.c b/system/lib/libc/musl/src/network/inet_ntop.c index 4bfef2c557ab4..f442f47d7b5aa 100644 --- a/system/lib/libc/musl/src/network/inet_ntop.c +++ b/system/lib/libc/musl/src/network/inet_ntop.c @@ -34,7 +34,12 @@ const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen for (i=best=0, max=2; buf[i]; i++) { if (i && buf[i] != ':') continue; j = strspn(buf+i, ":0"); - if (j>max) best=i, max=j; + /* The leading sequence of zeros (best==0) is + * disadvantaged compared to sequences elsewhere + * as it doesn't have a leading colon. One extra + * character is required for another sequence to + * beat it fairly. */ + if (j>max+(best==0)) best=i, max=j; } if (max>3) { buf[best] = buf[best+1] = ':'; diff --git a/system/lib/libc/musl/src/network/res_msend.c b/system/lib/libc/musl/src/network/res_msend.c index 86c2fcf4ff210..fcb52513002a2 100644 --- a/system/lib/libc/musl/src/network/res_msend.c +++ b/system/lib/libc/musl/src/network/res_msend.c @@ -83,8 +83,8 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries, int fd; int timeout, attempts, retry_interval, servfail_retry; union { - struct sockaddr_in sin; struct sockaddr_in6 sin6; + struct sockaddr_in sin; } sa = {0}, ns[MAXNS] = {{0}}; socklen_t sl = sizeof sa.sin; int nns = 0; diff --git a/system/lib/libc/musl/src/passwd/getgr_a.c b/system/lib/libc/musl/src/passwd/getgr_a.c index afeb1eceb5f86..8455040458017 100644 --- a/system/lib/libc/musl/src/passwd/getgr_a.c +++ b/system/lib/libc/musl/src/passwd/getgr_a.c @@ -71,6 +71,10 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t goto cleanup_f; } + if (groupbuf[GRMEMCNT] > (size_t)(INT32_MAX-1)) { + rv = ENOMEM; + goto cleanup_f; + } if (groupbuf[GRNAMELEN] > SIZE_MAX - groupbuf[GRPASSWDLEN]) { rv = ENOMEM; goto cleanup_f; @@ -127,7 +131,13 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t if (groupbuf[GRMEMCNT]) { mem[0][0] = *buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN]; for (ptr = mem[0][0], i = 0; ptr != mem[0][0]+grlist_len; ptr++) - if (!*ptr) mem[0][++i] = ptr+1; + if (!*ptr) + if (i #include +#include #include "syscall.h" int sigaltstack(const stack_t *restrict ss, stack_t *restrict old) { if (ss) { - if (!(ss->ss_flags & SS_DISABLE) && ss->ss_size < MINSIGSTKSZ) { + size_t min = sysconf(_SC_MINSIGSTKSZ); + if (!(ss->ss_flags & SS_DISABLE) && ss->ss_size < min) { errno = ENOMEM; return -1; } diff --git a/system/lib/libc/musl/src/signal/siglongjmp.c b/system/lib/libc/musl/src/signal/siglongjmp.c index bc317acce9317..53789b23959ed 100644 --- a/system/lib/libc/musl/src/signal/siglongjmp.c +++ b/system/lib/libc/musl/src/signal/siglongjmp.c @@ -5,5 +5,10 @@ _Noreturn void siglongjmp(sigjmp_buf buf, int ret) { + /* If sigsetjmp was called with nonzero savemask flag, the address + * longjmp will return to is inside of sigsetjmp. The signal mask + * will then be restored in the returned-to context instead of here, + * which matters if the context we are returning from may not have + * sufficient stack space for signal delivery. */ longjmp(buf, ret); } diff --git a/system/lib/libc/musl/src/signal/sigpause.c b/system/lib/libc/musl/src/signal/sigpause.c index 363d2fec27f9c..1587c3918da67 100644 --- a/system/lib/libc/musl/src/signal/sigpause.c +++ b/system/lib/libc/musl/src/signal/sigpause.c @@ -4,6 +4,6 @@ int sigpause(int sig) { sigset_t mask; sigprocmask(0, 0, &mask); - sigdelset(&mask, sig); + if (sigdelset(&mask, sig)) return -1; return sigsuspend(&mask); } diff --git a/system/lib/libc/musl/src/stdio/__stdio_write.c b/system/lib/libc/musl/src/stdio/__stdio_write.c index d2d89475b0f94..5356553d54e86 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_write.c +++ b/system/lib/libc/musl/src/stdio/__stdio_write.c @@ -11,6 +11,11 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) size_t rem = iov[0].iov_len + iov[1].iov_len; int iovcnt = 2; ssize_t cnt; + + if (!iov->iov_len) { + iov++; + iovcnt--; + } for (;;) { cnt = syscall(SYS_writev, f->fd, iov, iovcnt); if (cnt == rem) { diff --git a/system/lib/libc/musl/src/stdio/vfprintf.c b/system/lib/libc/musl/src/stdio/vfprintf.c index 497c5e19372dc..514a44dde0a90 100644 --- a/system/lib/libc/musl/src/stdio/vfprintf.c +++ b/system/lib/libc/musl/src/stdio/vfprintf.c @@ -166,7 +166,8 @@ static char *fmt_u(uintmax_t x, char *s) { unsigned long y; for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10; - for (y=x; y; y/=10) *--s = '0' + y%10; + for (y=x; y>=10; y/=10) *--s = '0' + y%10; + if (y) *--s = '0' + y; return s; } @@ -177,10 +178,16 @@ static char *fmt_u(uintmax_t x, char *s) typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; #endif -static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) +static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) { - uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion - + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion + int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG; + int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP; + /* One slot for 29 bits left of radix point, a slot for every 29-21=8 + * bits right of the radix point, and one final zero slot. */ + int max_mant_slots = 1 + (max_mant_dig-29+7)/8 + 1; + int max_exp_slots = (max_exp+max_mant_dig+28+8)/9; + int bufsize = max_mant_slots + max_exp_slots; + uint32_t big[bufsize]; uint32_t *a, *d, *r, *z; int e2=0, e, i, j, l; char buf[9+LDBL_MANT_DIG/4], *s; @@ -211,18 +218,11 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) if (y) e2--; if ((t|32)=='a') { - long double round = 8.0; - int re; - if (t&32) prefix += 9; pl += 2; - if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; - else re=LDBL_MANT_DIG/4-1-p; - - if (re) { - round *= 1<<(LDBL_MANT_DIG%4); - while (re--) round*=16; + if (p>=0 && p<(LDBL_MANT_DIG-1+3)/4) { + double round = scalbn(1, LDBL_MANT_DIG-1-(p*4)); if (*prefix=='-') { y=-y; y-=round; @@ -268,7 +268,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) if (y) y *= 0x1p28, e2-=28; if (e2<0) a=r=z=big; - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; + else a=r=z=big+sizeof(big)/sizeof(*big) - max_mant_slots - 1; do { *z = y; @@ -563,11 +563,11 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, case 'x': case 'X': a = fmt_x(arg.i, z, t&32); if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2; - if (0) { + goto ifmt_tail; case 'o': a = fmt_o(arg.i, z); if ((fl&ALT_FORM) && pINTMAX_MAX) { @@ -579,7 +579,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, } else pl=0; case 'u': a = fmt_u(arg.i, z); - } + ifmt_tail: if (xp && p<0) goto overflow; if (xp) fl &= ~ZERO_PAD; if (!arg.i && !p) { @@ -624,7 +624,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, case 'e': case 'f': case 'g': case 'a': case 'E': case 'F': case 'G': case 'A': if (xp && p<0) goto overflow; - l = fmt_fp(f, arg.f, w, p, fl, t); + l = fmt_fp(f, arg.f, w, p, fl, t, ps); if (l<0) goto overflow; continue; } diff --git a/system/lib/libc/musl/src/stdlib/qsort.c b/system/lib/libc/musl/src/stdlib/qsort.c index 314ddc29da1db..ab79dc6f40899 100644 --- a/system/lib/libc/musl/src/stdlib/qsort.c +++ b/system/lib/libc/musl/src/stdlib/qsort.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 by Valentin Ochs +/* Copyright (C) 2011 by Lynn Ochs * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to diff --git a/system/lib/libc/musl/src/string/strcasestr.c b/system/lib/libc/musl/src/string/strcasestr.c index af109f3611bd4..dc598bc388f71 100644 --- a/system/lib/libc/musl/src/string/strcasestr.c +++ b/system/lib/libc/musl/src/string/strcasestr.c @@ -4,6 +4,7 @@ char *strcasestr(const char *h, const char *n) { size_t l = strlen(n); + if (!l) return (char *)h; for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h; return 0; } diff --git a/system/lib/libc/musl/src/termios/cfgetospeed.c b/system/lib/libc/musl/src/termios/cfgetospeed.c index 55fa6f55c0ecb..de46a1d8a7f84 100644 --- a/system/lib/libc/musl/src/termios/cfgetospeed.c +++ b/system/lib/libc/musl/src/termios/cfgetospeed.c @@ -9,5 +9,5 @@ speed_t cfgetospeed(const struct termios *tio) speed_t cfgetispeed(const struct termios *tio) { - return cfgetospeed(tio); + return (tio->c_cflag & CIBAUD) / (CIBAUD/CBAUD); } diff --git a/system/lib/libc/musl/src/termios/cfsetospeed.c b/system/lib/libc/musl/src/termios/cfsetospeed.c index c9cbdd9d9d2e1..3eab092afa522 100644 --- a/system/lib/libc/musl/src/termios/cfsetospeed.c +++ b/system/lib/libc/musl/src/termios/cfsetospeed.c @@ -16,7 +16,11 @@ int cfsetospeed(struct termios *tio, speed_t speed) int cfsetispeed(struct termios *tio, speed_t speed) { - return speed ? cfsetospeed(tio, speed) : 0; + if (speed & ~CBAUD) { + errno = EINVAL; + return -1; + } + tio->c_cflag &= ~CIBAUD; + tio->c_cflag |= speed * (CIBAUD/CBAUD); + return 0; } - -weak_alias(cfsetospeed, cfsetspeed); diff --git a/system/lib/libc/musl/src/termios/cfsetspeed.c b/system/lib/libc/musl/src/termios/cfsetspeed.c new file mode 100644 index 0000000000000..2c369db93017b --- /dev/null +++ b/system/lib/libc/musl/src/termios/cfsetspeed.c @@ -0,0 +1,11 @@ +#define _BSD_SOURCE +#include +#include +#include + +int cfsetspeed(struct termios *tio, speed_t speed) +{ + int r = cfsetospeed(tio, speed); + if (!r) cfsetispeed(tio, 0); + return r; +} diff --git a/system/lib/libc/musl/src/thread/sem_post.c b/system/lib/libc/musl/src/thread/sem_post.c index 5c2517f23606d..1c8f763cacbd0 100644 --- a/system/lib/libc/musl/src/thread/sem_post.c +++ b/system/lib/libc/musl/src/thread/sem_post.c @@ -16,6 +16,6 @@ int sem_post(sem_t *sem) if (waiters <= 1) new &= ~0x80000000; } while (a_cas(sem->__val, val, new) != val); - if (val<0) __wake(sem->__val, waiters>1 ? 1 : -1, priv); + if (val<0 || waiters) __wake(sem->__val, waiters>1 ? 1 : -1, priv); return 0; } diff --git a/system/lib/libc/musl/src/time/__tz.c b/system/lib/libc/musl/src/time/__tz.c index c34b3eb755a54..54ed4cf6a783d 100644 --- a/system/lib/libc/musl/src/time/__tz.c +++ b/system/lib/libc/musl/src/time/__tz.c @@ -24,7 +24,6 @@ weak_alias(__tzname, tzname); static char std_name[TZNAME_MAX+1]; static char dst_name[TZNAME_MAX+1]; -const char __utc[] = "UTC"; static int dst_off; static int r0[5], r1[5]; diff --git a/system/lib/libc/musl/src/time/__utc.c b/system/lib/libc/musl/src/time/__utc.c new file mode 100644 index 0000000000000..9e8bfc58fb1c4 --- /dev/null +++ b/system/lib/libc/musl/src/time/__utc.c @@ -0,0 +1,3 @@ +#include "time_impl.h" + +const char __utc[] = "UTC"; diff --git a/system/lib/libc/musl/src/time/strptime.c b/system/lib/libc/musl/src/time/strptime.c index c54a0d8c4c52e..b114724286b79 100644 --- a/system/lib/libc/musl/src/time/strptime.c +++ b/system/lib/libc/musl/src/time/strptime.c @@ -59,6 +59,22 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri s = strptime(s, "%m/%d/%y", tm); if (!s) return 0; break; + case 'F': + /* Use temp buffer to implement the odd requirement + * that entire field be width-limited but the year + * subfield not itself be limited. */ + i = 0; + char tmp[20]; + if (*s == '-' || *s == '+') tmp[i++] = *s++; + while (*s=='0' && isdigit(s[1])) s++; + for (; *s && i<(size_t)w && i+1tm_hour; min = 0; @@ -114,6 +130,13 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri s = strptime(s, "%H:%M", tm); if (!s) return 0; break; + case 's': + /* Parse only. Effect on tm is unspecified + * and presently no effect is implemented.. */ + if (*s == '-') s++; + if (!isdigit(*s)) return 0; + while (isdigit(*s)) s++; + break; case 'S': dest = &tm->tm_sec; min = 0; @@ -125,11 +148,30 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri break; case 'U': case 'W': - /* Throw away result, for now. (FIXME?) */ + /* Throw away result of %U, %V, %W, %g, and %G. Effect + * is unspecified and there is no clear right choice. */ dest = &dummy; min = 0; range = 54; goto numeric_range; + case 'V': + dest = &dummy; + min = 1; + range = 53; + goto numeric_range; + case 'g': + dest = &dummy; + w = 2; + goto numeric_digits; + case 'G': + dest = &dummy; + if (w<0) w=4; + goto numeric_digits; + case 'u': + dest = &tm->tm_wday; + min = 1; + range = 7; + goto numeric_range; case 'w': dest = &tm->tm_wday; min = 0; @@ -154,6 +196,28 @@ char *strptime(const char *restrict s, const char *restrict f, struct tm *restri adj = 1900; want_century = 0; goto numeric_digits; + case 'z': + if (*s == '+') neg = 0; + else if (*s == '-') neg = 1; + else return 0; + for (i=0; i<4; i++) if (!isdigit(s[1+i])) return 0; + tm->__tm_gmtoff = (s[1]-'0')*36000+(s[2]-'0')*3600 + + (s[3]-'0')*600 + (s[4]-'0')*60; + if (neg) tm->__tm_gmtoff = -tm->__tm_gmtoff; + s += 5; + break; + case 'Z': + if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) { + tm->tm_isdst = 0; + s += len; + } else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) { + tm->tm_isdst = 1; + s += len; + } else { + /* FIXME: is this supposed to be an error? */ + while ((*s|32)-'a' <= 'z'-'a') s++; + } + break; case '%': if (*s++ != '%') return 0; break; diff --git a/system/lib/libc/musl/src/time/timer_create.c b/system/lib/libc/musl/src/time/timer_create.c index 9216b3abc5689..cc6c2236753e7 100644 --- a/system/lib/libc/musl/src/time/timer_create.c +++ b/system/lib/libc/musl/src/time/timer_create.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "pthread_impl.h" #include "atomic.h" @@ -12,7 +13,7 @@ struct ksigevent { }; struct start_args { - pthread_barrier_t b; + sem_t sem1, sem2; struct sigevent *sev; }; @@ -21,10 +22,16 @@ static void dummy_0() } weak_alias(dummy_0, __pthread_tsd_run_dtors); +static void timer_handler(int sig, siginfo_t *si, void *ctx) +{ +} + static void cleanup_fromsig(void *p) { pthread_t self = __pthread_self(); __pthread_tsd_run_dtors(); + __block_app_sigs(0); + __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGTIMER_SET, 0, _NSIG/8); self->cancel = 0; self->cancelbuf = 0; self->canceldisable = 0; @@ -42,7 +49,14 @@ static void *start(void *arg) void (*notify)(union sigval) = args->sev->sigev_notify_function; union sigval val = args->sev->sigev_value; - pthread_barrier_wait(&args->b); + /* The two-way semaphore synchronization ensures that we see + * self->cancel set by the parent if timer creation failed or + * self->timer_id if it succeeded, and informs the parent that + * we are done accessing the arguments so that the parent can + * proceed past their block lifetime. */ + while (sem_wait(&args->sem1)); + sem_post(&args->sem2); + if (self->cancel) return 0; for (;;) { @@ -90,7 +104,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict break; case SIGEV_THREAD: if (!init) { - struct sigaction sa = { .sa_handler = SIG_DFL }; + struct sigaction sa = { + .sa_sigaction = timer_handler, + .sa_flags = SA_SIGINFO | SA_RESTART + }; __libc_sigaction(SIGTIMER, &sa, 0); a_store(&init, 1); } @@ -99,7 +116,8 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict else pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_barrier_init(&args.b, 0, 2); + sem_init(&args.sem1, 0, 0); + sem_init(&args.sem2, 0, 0); args.sev = evp; __block_app_sigs(&set); @@ -120,7 +138,8 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict td->cancel = 1; } td->timer_id = timerid; - pthread_barrier_wait(&args.b); + sem_post(&args.sem1); + while (sem_wait(&args.sem2)); if (timerid < 0) return -1; *res = (void *)(INTPTR_MIN | (uintptr_t)td>>1); break; diff --git a/system/lib/libc/musl/src/unistd/isatty.c b/system/lib/libc/musl/src/unistd/isatty.c index 75a9c186a9418..21222edab6ee5 100644 --- a/system/lib/libc/musl/src/unistd/isatty.c +++ b/system/lib/libc/musl/src/unistd/isatty.c @@ -6,8 +6,6 @@ int isatty(int fd) { struct winsize wsz; - unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz); - if (r == 0) return 1; - if (errno != EBADF) errno = ENOTTY; - return 0; + /* +1 converts from error status (0/-1) to boolean (1/0) */ + return syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz) + 1; } diff --git a/system/lib/libc/musl/src/unistd/pause.c b/system/lib/libc/musl/src/unistd/pause.c index 90bbf4ca8ab53..90cc8db57b275 100644 --- a/system/lib/libc/musl/src/unistd/pause.c +++ b/system/lib/libc/musl/src/unistd/pause.c @@ -3,9 +3,5 @@ int pause(void) { -#ifdef SYS_pause - return syscall_cp(SYS_pause); -#else - return syscall_cp(SYS_ppoll, 0, 0, 0, 0); -#endif + return sys_pause_cp(); } diff --git a/system/lib/libc/musl/src/unistd/pwrite.c b/system/lib/libc/musl/src/unistd/pwrite.c index 869b69f03b88e..a008b3ecb5a45 100644 --- a/system/lib/libc/musl/src/unistd/pwrite.c +++ b/system/lib/libc/musl/src/unistd/pwrite.c @@ -1,7 +1,18 @@ +#define _GNU_SOURCE #include +#include +#include #include "syscall.h" ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { + if (ofs == -1) ofs--; + int r = __syscall_cp(SYS_pwritev2, fd, + (&(struct iovec){ .iov_base = (void *)buf, .iov_len = size }), + 1, (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); + if (r != -EOPNOTSUPP && r != -ENOSYS) + return __syscall_ret(r); + if (fcntl(fd, F_GETFL) & O_APPEND) + return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs)); } diff --git a/system/lib/libc/musl/src/unistd/pwritev.c b/system/lib/libc/musl/src/unistd/pwritev.c index becf9debfc3c8..44a53d8576274 100644 --- a/system/lib/libc/musl/src/unistd/pwritev.c +++ b/system/lib/libc/musl/src/unistd/pwritev.c @@ -1,10 +1,18 @@ -#define _BSD_SOURCE +#define _GNU_SOURCE #include #include +#include #include "syscall.h" ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { + if (ofs == -1) ofs--; + int r = __syscall_cp(SYS_pwritev2, fd, iov, count, + (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); + if (r != -EOPNOTSUPP && r != -ENOSYS) + return __syscall_ret(r); + if (fcntl(fd, F_GETFL) & O_APPEND) + return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwritev, fd, iov, count, (long)(ofs), (long)(ofs>>32)); } From a67d1304322ca7fb7df55eccb2b2a46230880f06 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 11:45:57 +0200 Subject: [PATCH 04/17] musl: reapply Emscripten-specific changes This reverts commit 8afc0844aa49705c3c48c9e093ee6b749c442a3e. --- .../libc/musl/arch/emscripten/atomic_arch.h | 111 ++++ .../libc/musl/arch/emscripten/bits/alltypes.h | 481 ++++++++++++++++++ .../musl/arch/emscripten/bits/alltypes.h.in | 43 ++ .../libc/musl/arch/emscripten/bits/endian.h | 1 + .../libc/musl/arch/emscripten/bits/errno.h | 144 ++++++ .../lib/libc/musl/arch/emscripten/bits/fenv.h | 27 + .../libc/musl/arch/emscripten/bits/float.h | 17 + .../libc/musl/arch/emscripten/bits/limits.h | 1 + .../libc/musl/arch/emscripten/bits/posix.h | 2 + .../lib/libc/musl/arch/emscripten/bits/reg.h | 6 + .../libc/musl/arch/emscripten/bits/setjmp.h | 1 + .../libc/musl/arch/emscripten/bits/signal.h | 123 +++++ .../lib/libc/musl/arch/emscripten/bits/stat.h | 26 + .../libc/musl/arch/emscripten/bits/syscall.h | 89 ++++ .../lib/libc/musl/arch/emscripten/bits/user.h | 48 ++ .../lib/libc/musl/arch/emscripten/crt_arch.h | 0 system/lib/libc/musl/arch/emscripten/kstat.h | 3 + .../libc/musl/arch/emscripten/pthread_arch.h | 5 + .../libc/musl/arch/emscripten/syscall_arch.h | 8 + .../lib/libc/musl/arch/generic/bits/stdarg.h | 4 + system/lib/libc/musl/config.mak | 32 ++ system/lib/libc/musl/configure | 4 +- system/lib/libc/musl/include/alltypes.h.in | 35 +- system/lib/libc/musl/include/fcntl.h | 10 + system/lib/libc/musl/include/features.h | 7 + system/lib/libc/musl/include/inttypes.h | 7 +- system/lib/libc/musl/include/limits.h | 7 + system/lib/libc/musl/include/locale.h | 2 +- system/lib/libc/musl/include/setjmp.h | 6 + system/lib/libc/musl/include/signal.h | 2 +- system/lib/libc/musl/include/stddef.h | 2 +- system/lib/libc/musl/include/stdint.h | 185 +++---- system/lib/libc/musl/include/stdio.h | 12 +- system/lib/libc/musl/include/stdlib.h | 2 +- system/lib/libc/musl/include/string.h | 2 +- system/lib/libc/musl/include/time.h | 2 +- system/lib/libc/musl/include/unistd.h | 40 +- system/lib/libc/musl/include/wchar.h | 2 +- system/lib/libc/musl/src/conf/confstr.c | 19 + system/lib/libc/musl/src/conf/fpathconf.c | 2 +- system/lib/libc/musl/src/conf/sysconf.c | 35 +- system/lib/libc/musl/src/dirent/opendir.c | 4 + system/lib/libc/musl/src/env/__environ.c | 37 ++ .../lib/libc/musl/src/env/__stack_chk_fail.c | 5 + .../libc/musl/src/errno/__errno_location.c | 11 + system/lib/libc/musl/src/errno/__strerror.h | 17 +- system/lib/libc/musl/src/errno/strerror.c | 16 + system/lib/libc/musl/src/exit/_Exit.c | 4 + system/lib/libc/musl/src/exit/abort.c | 13 + system/lib/libc/musl/src/exit/atexit.c | 14 +- system/lib/libc/musl/src/fcntl/fcntl.c | 32 +- system/lib/libc/musl/src/fcntl/open.c | 2 + system/lib/libc/musl/src/internal/dynlink.h | 36 ++ system/lib/libc/musl/src/internal/libc.c | 2 + system/lib/libc/musl/src/internal/libc.h | 6 + system/lib/libc/musl/src/internal/libm.h | 8 + .../lib/libc/musl/src/internal/locale_impl.h | 16 + system/lib/libc/musl/src/internal/progname.c | 37 ++ .../internal/proxying_notification_state.h | 18 + .../lib/libc/musl/src/internal/pthread_impl.h | 92 +++- .../lib/libc/musl/src/internal/stdio_impl.h | 16 +- system/lib/libc/musl/src/internal/syscall.h | 54 +- system/lib/libc/musl/src/linux/gettid.c | 28 + system/lib/libc/musl/src/linux/sbrk.c | 3 + system/lib/libc/musl/src/linux/statx.c | 4 + system/lib/libc/musl/src/locale/catclose.c | 2 + system/lib/libc/musl/src/locale/catgets.c | 6 + system/lib/libc/musl/src/locale/catopen.c | 4 + system/lib/libc/musl/src/locale/dcngettext.c | 2 +- system/lib/libc/musl/src/locale/locale_map.c | 4 + system/lib/libc/musl/src/locale/uselocale.c | 11 + .../lib/libc/musl/src/malloc/reallocarray.c | 17 + system/lib/libc/musl/src/math/ceil.c | 8 + system/lib/libc/musl/src/math/ceilf.c | 6 + system/lib/libc/musl/src/math/copysign.c | 6 + system/lib/libc/musl/src/math/copysignf.c | 6 + system/lib/libc/musl/src/math/fabs.c | 6 + system/lib/libc/musl/src/math/fabsf.c | 6 + system/lib/libc/musl/src/math/floor.c | 8 + system/lib/libc/musl/src/math/floorf.c | 6 + system/lib/libc/musl/src/math/fma.c | 2 + system/lib/libc/musl/src/math/fmaf.c | 2 + system/lib/libc/musl/src/math/fmal.c | 2 + system/lib/libc/musl/src/math/fmax.c | 5 + system/lib/libc/musl/src/math/fmaxf.c | 5 + system/lib/libc/musl/src/math/fmin.c | 5 + system/lib/libc/musl/src/math/fminf.c | 5 + system/lib/libc/musl/src/math/ilogb.c | 2 + system/lib/libc/musl/src/math/ilogbf.c | 2 + system/lib/libc/musl/src/math/ilogbl.c | 4 + system/lib/libc/musl/src/math/log2_small.c | 122 +++++ system/lib/libc/musl/src/math/log_small.c | 118 +++++ system/lib/libc/musl/src/math/pow_small.c | 328 ++++++++++++ system/lib/libc/musl/src/math/rint.c | 8 + system/lib/libc/musl/src/math/rintf.c | 8 + system/lib/libc/musl/src/math/sqrt.c | 8 + system/lib/libc/musl/src/math/sqrtf.c | 8 + system/lib/libc/musl/src/math/sqrtl.c | 4 + system/lib/libc/musl/src/math/trunc.c | 6 + system/lib/libc/musl/src/math/truncf.c | 6 + system/lib/libc/musl/src/misc/getentropy.c | 8 + system/lib/libc/musl/src/misc/getopt.c | 2 +- system/lib/libc/musl/src/misc/ioctl.c | 5 + system/lib/libc/musl/src/mman/mmap.c | 1 + system/lib/libc/musl/src/mman/munmap.c | 1 + .../lib/libc/musl/src/multibyte/mbsrtowcs.c | 6 +- .../lib/libc/musl/src/network/freeaddrinfo.c | 8 + .../libc/musl/src/network/if_indextoname.c | 4 + .../libc/musl/src/network/if_nametoindex.c | 4 + system/lib/libc/musl/src/network/netlink.c | 4 + system/lib/libc/musl/src/network/ns_parse.c | 60 +-- system/lib/libc/musl/src/network/recvmmsg.c | 2 +- system/lib/libc/musl/src/network/recvmsg.c | 4 +- system/lib/libc/musl/src/network/res_msend.c | 8 + system/lib/libc/musl/src/network/sendmsg.c | 2 +- system/lib/libc/musl/src/process/fexecve.c | 2 + system/lib/libc/musl/src/sched/sched_yield.c | 14 + system/lib/libc/musl/src/select/ppoll.c | 11 + system/lib/libc/musl/src/select/pselect.c | 15 + system/lib/libc/musl/src/select/select.c | 85 +++- system/lib/libc/musl/src/signal/block.c | 6 + system/lib/libc/musl/src/signal/getitimer.c | 11 + system/lib/libc/musl/src/signal/setitimer.c | 116 +++++ system/lib/libc/musl/src/stat/fchmod.c | 8 + system/lib/libc/musl/src/stat/fchmodat.c | 10 + system/lib/libc/musl/src/stat/fstatat.c | 18 + system/lib/libc/musl/src/stdio/__fdopen.c | 2 + .../lib/libc/musl/src/stdio/__fopen_rb_ca.c | 2 + system/lib/libc/musl/src/stdio/__lockfile.c | 6 +- .../lib/libc/musl/src/stdio/__stdio_close.c | 4 + system/lib/libc/musl/src/stdio/__stdio_read.c | 8 + .../lib/libc/musl/src/stdio/__stdio_write.c | 8 + system/lib/libc/musl/src/stdio/fopen.c | 6 + system/lib/libc/musl/src/stdio/fprintf.c | 22 + system/lib/libc/musl/src/stdio/freopen.c | 2 + system/lib/libc/musl/src/stdio/getc.h | 2 +- system/lib/libc/musl/src/stdio/printf.c | 23 + system/lib/libc/musl/src/stdio/putc.h | 2 +- system/lib/libc/musl/src/stdio/sprintf.c | 23 + system/lib/libc/musl/src/stdio/stdout.c | 21 + system/lib/libc/musl/src/stdio/tmpfile.c | 4 + system/lib/libc/musl/src/stdio/vfprintf.c | 99 +++- system/lib/libc/musl/src/stdio/vsnprintf.c | 55 ++ system/lib/libc/musl/src/stdio/vsprintf.c | 13 + system/lib/libc/musl/src/stdlib/strtol.c | 84 +++ system/lib/libc/musl/src/string/memchr.c | 3 +- system/lib/libc/musl/src/string/memcmp.c | 24 + system/lib/libc/musl/src/string/stpcpy.c | 4 +- system/lib/libc/musl/src/string/stpncpy.c | 5 +- system/lib/libc/musl/src/string/strchrnul.c | 4 +- system/lib/libc/musl/src/string/strlen.c | 3 +- system/lib/libc/musl/src/temp/__randname.c | 5 + system/lib/libc/musl/src/thread/__timedwait.c | 20 + system/lib/libc/musl/src/thread/__wait.c | 9 + .../lib/libc/musl/src/thread/pthread_atfork.c | 6 + .../libc/musl/src/thread/pthread_attr_get.c | 8 +- .../musl/src/thread/pthread_barrier_wait.c | 11 +- .../lib/libc/musl/src/thread/pthread_cancel.c | 16 +- .../musl/src/thread/pthread_cond_timedwait.c | 17 + .../src/thread/pthread_condattr_setpshared.c | 3 + .../lib/libc/musl/src/thread/pthread_detach.c | 18 + .../libc/musl/src/thread/pthread_getattr_np.c | 5 + .../musl/src/thread/pthread_getconcurrency.c | 2 + .../musl/src/thread/pthread_getcpuclockid.c | 5 + .../musl/src/thread/pthread_getschedparam.c | 5 + .../lib/libc/musl/src/thread/pthread_join.c | 37 ++ .../libc/musl/src/thread/pthread_key_create.c | 4 + .../libc/musl/src/thread/pthread_mutex_lock.c | 3 + .../musl/src/thread/pthread_mutex_timedlock.c | 16 + .../musl/src/thread/pthread_mutex_trylock.c | 16 +- .../musl/src/thread/pthread_mutex_unlock.c | 4 + .../thread/pthread_mutexattr_setprotocol.c | 2 + .../src/thread/pthread_mutexattr_setpshared.c | 3 + .../src/thread/pthread_mutexattr_setrobust.c | 2 + .../src/thread/pthread_rwlock_timedwrlock.c | 14 +- .../src/thread/pthread_rwlock_trywrlock.c | 5 + .../musl/src/thread/pthread_rwlock_unlock.c | 6 + .../thread/pthread_rwlockattr_setpshared.c | 3 + .../musl/src/thread/pthread_setconcurrency.c | 2 + .../musl/src/thread/pthread_setschedparam.c | 5 + .../musl/src/thread/pthread_setschedprio.c | 5 + system/lib/libc/musl/src/thread/sem_init.c | 3 + .../lib/libc/musl/src/thread/sem_timedwait.c | 3 + system/lib/libc/musl/src/thread/thrd_create.c | 9 + system/lib/libc/musl/src/thread/thrd_join.c | 6 +- system/lib/libc/musl/src/thread/thrd_yield.c | 2 + system/lib/libc/musl/src/time/__map_file.c | 4 + system/lib/libc/musl/src/time/__tz.c | 31 +- system/lib/libc/musl/src/time/__utc.c | 2 +- system/lib/libc/musl/src/time/clock_getres.c | 15 + system/lib/libc/musl/src/time/clock_gettime.c | 19 + .../lib/libc/musl/src/time/clock_nanosleep.c | 23 + system/lib/libc/musl/src/time/clock_settime.c | 9 + system/lib/libc/musl/src/time/localtime_r.c | 6 + system/lib/libc/musl/src/time/strftime.c | 6 + system/lib/libc/musl/src/unistd/close.c | 6 + system/lib/libc/musl/src/unistd/dup2.c | 7 + system/lib/libc/musl/src/unistd/faccessat.c | 6 + system/lib/libc/musl/src/unistd/fchdir.c | 8 + system/lib/libc/musl/src/unistd/fchown.c | 10 +- system/lib/libc/musl/src/unistd/fsync.c | 4 + system/lib/libc/musl/src/unistd/isatty.c | 18 + system/lib/libc/musl/src/unistd/lseek.c | 5 + system/lib/libc/musl/src/unistd/pipe2.c | 2 + system/lib/libc/musl/src/unistd/pread.c | 12 + system/lib/libc/musl/src/unistd/preadv.c | 8 + system/lib/libc/musl/src/unistd/pwrite.c | 12 + system/lib/libc/musl/src/unistd/pwritev.c | 8 + system/lib/libc/musl/src/unistd/read.c | 12 + system/lib/libc/musl/src/unistd/readv.c | 8 + system/lib/libc/musl/src/unistd/setxid.c | 9 +- system/lib/libc/musl/src/unistd/write.c | 12 + system/lib/libc/musl/src/unistd/writev.c | 11 + system/lib/libc/musl/tools/mkalltypes.sed | 15 + 214 files changed, 3975 insertions(+), 215 deletions(-) create mode 100644 system/lib/libc/musl/arch/emscripten/atomic_arch.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/alltypes.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in create mode 100644 system/lib/libc/musl/arch/emscripten/bits/endian.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/errno.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/fenv.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/float.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/limits.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/posix.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/reg.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/setjmp.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/signal.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/stat.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/syscall.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/user.h create mode 100644 system/lib/libc/musl/arch/emscripten/crt_arch.h create mode 100644 system/lib/libc/musl/arch/emscripten/kstat.h create mode 100644 system/lib/libc/musl/arch/emscripten/pthread_arch.h create mode 100644 system/lib/libc/musl/arch/emscripten/syscall_arch.h create mode 100644 system/lib/libc/musl/arch/generic/bits/stdarg.h create mode 100644 system/lib/libc/musl/config.mak create mode 100644 system/lib/libc/musl/src/internal/progname.c create mode 100644 system/lib/libc/musl/src/internal/proxying_notification_state.h create mode 100644 system/lib/libc/musl/src/malloc/reallocarray.c create mode 100644 system/lib/libc/musl/src/math/log2_small.c create mode 100644 system/lib/libc/musl/src/math/log_small.c create mode 100644 system/lib/libc/musl/src/math/pow_small.c create mode 100644 system/lib/libc/musl/tools/mkalltypes.sed diff --git a/system/lib/libc/musl/arch/emscripten/atomic_arch.h b/system/lib/libc/musl/arch/emscripten/atomic_arch.h new file mode 100644 index 0000000000000..937fd43fc97e2 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/atomic_arch.h @@ -0,0 +1,111 @@ +#ifndef _INTERNAL_ATOMIC_H +#define _INTERNAL_ATOMIC_H + +#include + +#define a_clz_l __builtin_clz +#define a_ctz_l __builtin_ctz +#define a_clz_64 __builtin_clzll +#define a_ctz_64 __builtin_ctzll + +#define a_and_64 a_and_64 +static inline void a_and_64(volatile uint64_t *p, uint64_t v) +{ + *p &= v; +} + +#define a_or_64 a_or_64 +static inline void a_or_64(volatile uint64_t *p, uint64_t v) +{ + *p |= v; +} + +#define a_store_l a_store_l +static inline void a_store_l(volatile void *p, long x) +{ + __c11_atomic_store((_Atomic long*)p, x, __ATOMIC_SEQ_CST); +} + +#define a_or_l a_or_l +static inline void a_or_l(volatile void *p, long v) +{ + __c11_atomic_fetch_or((_Atomic long*)p, v, __ATOMIC_SEQ_CST); +} +#define a_cas_p a_cas_p +static inline void *a_cas_p(volatile void *p, void *t, void *s) +{ + uintptr_t expected = (uintptr_t)t; + __c11_atomic_compare_exchange_strong((_Atomic uintptr_t*)p, &expected, (uintptr_t)s, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return (void*)expected; +} + +#define a_cas_l a_cas_l +static inline long a_cas_l(volatile void *p, long t, long s) +{ + long expected = t; + __c11_atomic_compare_exchange_strong((_Atomic long*)p, &expected, s, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return expected; +} + +#define a_cas a_cas +static inline int a_cas(volatile int *p, int t, int s) +{ + int expected = t; + __c11_atomic_compare_exchange_strong((_Atomic int*)p, &expected, s, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + return expected; +} + +#define a_or a_or +static inline void a_or(volatile void *p, int v) +{ + __c11_atomic_fetch_or((_Atomic int*)p, v, __ATOMIC_SEQ_CST); +} + +#define a_and a_and +static inline void a_and(volatile void *p, int v) +{ + __c11_atomic_fetch_and((_Atomic int*)p, v, __ATOMIC_SEQ_CST); +} + +#define a_swap a_swap +static inline int a_swap(volatile int *x, int v) +{ + return __c11_atomic_exchange((_Atomic int*)x, v, __ATOMIC_SEQ_CST); +} + +#define a_fetch_add a_fetch_add +static inline int a_fetch_add(volatile int *x, int v) +{ + return __c11_atomic_fetch_add((_Atomic int*)x, v, __ATOMIC_SEQ_CST); +} + +#define a_inc a_inc +static inline void a_inc(volatile int *x) +{ + __c11_atomic_fetch_add((_Atomic int*)x, 1, __ATOMIC_SEQ_CST); +} + +#define a_dec a_dec +static inline void a_dec(volatile int *x) +{ + __c11_atomic_fetch_sub((_Atomic int*)x, 1, __ATOMIC_SEQ_CST); +} + +#define a_store a_store +static inline void a_store(volatile int *p, int x) +{ + __c11_atomic_store((_Atomic int*)p, x, __ATOMIC_SEQ_CST); +} + +#define a_spin a_spin +static inline void a_spin() +{ +} + +#define a_crash a_crash +static inline void a_crash() +{ + __builtin_trap(); +} + +#endif diff --git a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h new file mode 100644 index 0000000000000..0db4d998f29c8 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h @@ -0,0 +1,481 @@ +/* + * The .h version of this file is generated from the .h.in. + * See update_alltypes.sh. + */ +#define _Addr __PTRDIFF_TYPE__ +#define _Int64 __INT64_TYPE__ +#define _Reg __PTRDIFF_TYPE__ + +#define __BYTE_ORDER 1234 +#define __LONG_MAX __LONG_MAX__ + +#ifndef __cplusplus +#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) +typedef __WCHAR_TYPE__ wchar_t; +#define __DEFINED_wchar_t +#endif + +#endif +#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) +typedef __WINT_TYPE__ wint_t; +#define __DEFINED_wint_t +#endif + + +// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 +#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) +typedef int blkcnt_t; +#define __DEFINED_blkcnt_t +#endif + +#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) +typedef int blksize_t; +#define __DEFINED_blksize_t +#endif + +#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) +typedef int clock_t; +#define __DEFINED_clock_t +#endif + +#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) +typedef unsigned int dev_t; +#define __DEFINED_dev_t +#endif + +#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) +typedef int suseconds_t; +#define __DEFINED_suseconds_t +#endif + +#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) +typedef unsigned int wctype_t; +#define __DEFINED_wctype_t +#endif + + +#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) +typedef float float_t; +#define __DEFINED_float_t +#endif + +#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) +typedef double double_t; +#define __DEFINED_double_t +#endif + + +#ifndef __cplusplus +#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) +typedef struct { _Alignas(8) long long __ll; long double __ld; } max_align_t; +#define __DEFINED_max_align_t +#endif + +#elif defined(__GNUC__) +#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) +typedef struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t; +#define __DEFINED_max_align_t +#endif + +#else +#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) +typedef struct { alignas(8) long long __ll; long double __ld; } max_align_t; +#define __DEFINED_max_align_t +#endif + +#endif + +// For canvas transfer implementation in Emscripten, use an extra control field +// to pass a pointer to a string denoting the WebGL canvases to transfer. +#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) +typedef struct { union { int __i[10]; volatile int __vi[10]; unsigned long __s[10]; } __u; const char *_a_transferredcanvases; } pthread_attr_t; +#define __DEFINED_pthread_attr_t +#endif + + +// END EMSCRIPTEN-SPECIFIC DEFINITIONS +// +// Below here are the shared musl definitions. The emscripten-specific definitions above will take precedence +// due to the `__DEFINED_` macro system. +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __USE_TIME_BITS64 1 + +#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) +typedef unsigned _Addr size_t; +#define __DEFINED_size_t +#endif + +#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) +typedef unsigned _Addr uintptr_t; +#define __DEFINED_uintptr_t +#endif + +#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) +typedef _Addr ptrdiff_t; +#define __DEFINED_ptrdiff_t +#endif + +#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) +typedef _Addr ssize_t; +#define __DEFINED_ssize_t +#endif + +#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) +typedef _Addr intptr_t; +#define __DEFINED_intptr_t +#endif + +#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t) +typedef _Addr regoff_t; +#define __DEFINED_regoff_t +#endif + +#if defined(__NEED_register_t) && !defined(__DEFINED_register_t) +typedef _Reg register_t; +#define __DEFINED_register_t +#endif + +#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) +typedef _Int64 time_t; +#define __DEFINED_time_t +#endif + +#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) +typedef _Int64 suseconds_t; +#define __DEFINED_suseconds_t +#endif + + +// XXX EMSCRIPTEN: This file has been modified from the upstream musl version +// to make use of clang pre-defined macros whereever possible, eliminating +// possible inconsistencies. + +#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) +typedef __INT8_TYPE__ int8_t; +#define __DEFINED_int8_t +#endif + +#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) +typedef __INT16_TYPE__ int16_t; +#define __DEFINED_int16_t +#endif + +#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) +typedef __INT32_TYPE__ int32_t; +#define __DEFINED_int32_t +#endif + +#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) +typedef __INT64_TYPE__ int64_t; +#define __DEFINED_int64_t +#endif + +#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) +typedef __INTMAX_TYPE__ intmax_t; +#define __DEFINED_intmax_t +#endif + +#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) +typedef __UINT8_TYPE__ uint8_t; +#define __DEFINED_uint8_t +#endif + +#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) +typedef __UINT16_TYPE__ uint16_t; +#define __DEFINED_uint16_t +#endif + +#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) +typedef __UINT32_TYPE__ uint32_t; +#define __DEFINED_uint32_t +#endif + +#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) +typedef __UINT64_TYPE__ uint64_t; +#define __DEFINED_uint64_t +#endif + +#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t) +typedef __UINT64_TYPE__ u_int64_t; +#define __DEFINED_u_int64_t +#endif + +#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) +typedef __UINTMAX_TYPE__ uintmax_t; +#define __DEFINED_uintmax_t +#endif + + +#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) +typedef unsigned mode_t; +#define __DEFINED_mode_t +#endif + +#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) +typedef unsigned _Reg nlink_t; +#define __DEFINED_nlink_t +#endif + +#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) +typedef _Int64 off_t; +#define __DEFINED_off_t +#endif + +#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) +typedef unsigned _Int64 ino_t; +#define __DEFINED_ino_t +#endif + +#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) +typedef unsigned _Int64 dev_t; +#define __DEFINED_dev_t +#endif + +#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) +typedef long blksize_t; +#define __DEFINED_blksize_t +#endif + +#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) +typedef _Int64 blkcnt_t; +#define __DEFINED_blkcnt_t +#endif + +#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) +typedef unsigned _Int64 fsblkcnt_t; +#define __DEFINED_fsblkcnt_t +#endif + +#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) +typedef unsigned _Int64 fsfilcnt_t; +#define __DEFINED_fsfilcnt_t +#endif + + +#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) +typedef unsigned wint_t; +#define __DEFINED_wint_t +#endif + +#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) +typedef unsigned long wctype_t; +#define __DEFINED_wctype_t +#endif + + +#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) +typedef void * timer_t; +#define __DEFINED_timer_t +#endif + +#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) +typedef int clockid_t; +#define __DEFINED_clockid_t +#endif + +#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) +typedef long clock_t; +#define __DEFINED_clock_t +#endif + +#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) +struct timeval { time_t tv_sec; suseconds_t tv_usec; }; +#define __DEFINED_struct_timeval +#endif + +#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) +struct timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); }; +#define __DEFINED_struct_timespec +#endif + + +#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) +typedef int pid_t; +#define __DEFINED_pid_t +#endif + +#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) +typedef unsigned id_t; +#define __DEFINED_id_t +#endif + +#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) +typedef unsigned uid_t; +#define __DEFINED_uid_t +#endif + +#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) +typedef unsigned gid_t; +#define __DEFINED_gid_t +#endif + +#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) +typedef int key_t; +#define __DEFINED_key_t +#endif + +#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) +typedef unsigned useconds_t; +#define __DEFINED_useconds_t +#endif + + +#ifdef __cplusplus +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef unsigned long pthread_t; +#define __DEFINED_pthread_t +#endif + +#else +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef struct __pthread * pthread_t; +#define __DEFINED_pthread_t +#endif + +#endif +#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) +typedef int pthread_once_t; +#define __DEFINED_pthread_once_t +#endif + +#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) +typedef unsigned pthread_key_t; +#define __DEFINED_pthread_key_t +#endif + +#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) +typedef int pthread_spinlock_t; +#define __DEFINED_pthread_spinlock_t +#endif + +#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) +typedef struct { unsigned __attr; } pthread_mutexattr_t; +#define __DEFINED_pthread_mutexattr_t +#endif + +#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) +typedef struct { unsigned __attr; } pthread_condattr_t; +#define __DEFINED_pthread_condattr_t +#endif + +#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) +typedef struct { unsigned __attr; } pthread_barrierattr_t; +#define __DEFINED_pthread_barrierattr_t +#endif + +#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) +typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; +#define __DEFINED_pthread_rwlockattr_t +#endif + + +#if defined(__NEED_struct__IO_FILE) && !defined(__DEFINED_struct__IO_FILE) +struct _IO_FILE { char __x; }; +#define __DEFINED_struct__IO_FILE +#endif + +#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) +typedef struct _IO_FILE FILE; +#define __DEFINED_FILE +#endif + + +#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) +typedef __builtin_va_list va_list; +#define __DEFINED_va_list +#endif + +#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list) +typedef __builtin_va_list __isoc_va_list; +#define __DEFINED___isoc_va_list +#endif + + +#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t) +typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; +#define __DEFINED_mbstate_t +#endif + + +#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) +typedef struct __locale_struct * locale_t; +#define __DEFINED_locale_t +#endif + + +// Musl uses 128 bytes for sigset_t, presumably for some kind of ABI +// compatability with the kernel or GLIBC, but in emscripten we can be precise. +// Since we have _NSIG = 65 which only need 2 `long`s for the bitmask. +// The signals we support are +// 1 - 31 - standard POSIX signals (see emscripten/bits/signal.h) +// 32 - 34 - pthread-specific signals (see pthread_impl.h> +// 35 - 65 - user-defined RT signals (we don't currently have any test coverage of these). +#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) +typedef struct __sigset_t { unsigned long __bits[2]; } sigset_t; +#define __DEFINED_sigset_t +#endif + + +#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) +struct iovec { void *iov_base; size_t iov_len; }; +#define __DEFINED_struct_iovec +#endif + + +#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize) +struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; }; +#define __DEFINED_struct_winsize +#endif + + +#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) +typedef unsigned socklen_t; +#define __DEFINED_socklen_t +#endif + +#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) +typedef unsigned short sa_family_t; +#define __DEFINED_sa_family_t +#endif + + +#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) +typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t; +#define __DEFINED_pthread_attr_t +#endif + +#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) +typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t; +#define __DEFINED_pthread_mutex_t +#endif + +#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t) +typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t; +#define __DEFINED_mtx_t +#endif + +#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } pthread_cond_t; +#define __DEFINED_pthread_cond_t +#endif + +#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t) +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } cnd_t; +#define __DEFINED_cnd_t +#endif + +#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) +typedef struct { union { int __i[sizeof(long)==8?14:8]; volatile int __vi[sizeof(long)==8?14:8]; void *__p[sizeof(long)==8?7:8]; } __u; } pthread_rwlock_t; +#define __DEFINED_pthread_rwlock_t +#endif + +#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) +typedef struct { union { int __i[sizeof(long)==8?8:5]; volatile int __vi[sizeof(long)==8?8:5]; void *__p[sizeof(long)==8?4:5]; } __u; } pthread_barrier_t; +#define __DEFINED_pthread_barrier_t +#endif + + +#undef _Addr +#undef _Int64 +#undef _Reg diff --git a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in new file mode 100644 index 0000000000000..1f3168b2f8627 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h.in @@ -0,0 +1,43 @@ +/* + * The .h version of this file is generated from the .h.in. + * See update_alltypes.sh. + */ +#define _Addr __PTRDIFF_TYPE__ +#define _Int64 __INT64_TYPE__ +#define _Reg __PTRDIFF_TYPE__ + +#define __BYTE_ORDER 1234 +#define __LONG_MAX __LONG_MAX__ + +#ifndef __cplusplus +TYPEDEF __WCHAR_TYPE__ wchar_t; +#endif +TYPEDEF __WINT_TYPE__ wint_t; + +// XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 +TYPEDEF int blkcnt_t; +TYPEDEF int blksize_t; +TYPEDEF int clock_t; +TYPEDEF unsigned int dev_t; +TYPEDEF int suseconds_t; +TYPEDEF unsigned int wctype_t; + +TYPEDEF float float_t; +TYPEDEF double double_t; + +#ifndef __cplusplus +TYPEDEF struct { _Alignas(8) long long __ll; long double __ld; } max_align_t; +#elif defined(__GNUC__) +TYPEDEF struct { __attribute__((__aligned__(8))) long long __ll; long double __ld; } max_align_t; +#else +TYPEDEF struct { alignas(8) long long __ll; long double __ld; } max_align_t; +#endif + +// For canvas transfer implementation in Emscripten, use an extra control field +// to pass a pointer to a string denoting the WebGL canvases to transfer. +TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; unsigned long __s[10]; } __u; const char *_a_transferredcanvases; } pthread_attr_t; + +// END EMSCRIPTEN-SPECIFIC DEFINITIONS +// +// Below here are the shared musl definitions. The emscripten-specific definitions above will take precedence +// due to the `__DEFINED_` macro system. diff --git a/system/lib/libc/musl/arch/emscripten/bits/endian.h b/system/lib/libc/musl/arch/emscripten/bits/endian.h new file mode 100644 index 0000000000000..172c338f5080a --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/endian.h @@ -0,0 +1 @@ +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/system/lib/libc/musl/arch/emscripten/bits/errno.h b/system/lib/libc/musl/arch/emscripten/bits/errno.h new file mode 100644 index 0000000000000..43a8a6bac049b --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/errno.h @@ -0,0 +1,144 @@ +#include + +#define EPERM __WASI_ERRNO_PERM +#define ENOENT __WASI_ERRNO_NOENT +#define ESRCH __WASI_ERRNO_SRCH +#define EINTR __WASI_ERRNO_INTR +#define EIO __WASI_ERRNO_IO +#define ENXIO __WASI_ERRNO_NXIO +#define E2BIG __WASI_ERRNO_2BIG +#define ENOEXEC __WASI_ERRNO_NOEXEC +#define EBADF __WASI_ERRNO_BADF +#define ECHILD __WASI_ERRNO_CHILD +#define EAGAIN __WASI_ERRNO_AGAIN +#define ENOMEM __WASI_ERRNO_NOMEM +#define EACCES __WASI_ERRNO_ACCES +#define EFAULT __WASI_ERRNO_FAULT +#define EBUSY __WASI_ERRNO_BUSY +#define EEXIST __WASI_ERRNO_EXIST +#define EXDEV __WASI_ERRNO_XDEV +#define ENODEV __WASI_ERRNO_NODEV +#define ENOTDIR __WASI_ERRNO_NOTDIR +#define EISDIR __WASI_ERRNO_ISDIR +#define EINVAL __WASI_ERRNO_INVAL +#define ENFILE __WASI_ERRNO_NFILE +#define EMFILE __WASI_ERRNO_MFILE +#define ENOTTY __WASI_ERRNO_NOTTY +#define ETXTBSY __WASI_ERRNO_TXTBSY +#define EFBIG __WASI_ERRNO_FBIG +#define ENOSPC __WASI_ERRNO_NOSPC +#define ESPIPE __WASI_ERRNO_SPIPE +#define EROFS __WASI_ERRNO_ROFS +#define EMLINK __WASI_ERRNO_MLINK +#define EPIPE __WASI_ERRNO_PIPE +#define EDOM __WASI_ERRNO_DOM +#define ERANGE __WASI_ERRNO_RANGE +#define EDEADLK __WASI_ERRNO_DEADLK +#define ENAMETOOLONG __WASI_ERRNO_NAMETOOLONG +#define ENOLCK __WASI_ERRNO_NOLCK +#define ENOSYS __WASI_ERRNO_NOSYS +#define ENOTEMPTY __WASI_ERRNO_NOTEMPTY +#define ELOOP __WASI_ERRNO_LOOP +#define ENOMSG __WASI_ERRNO_NOMSG +#define EIDRM __WASI_ERRNO_IDRM +#define ENOLINK __WASI_ERRNO_NOLINK +#define EPROTO __WASI_ERRNO_PROTO +#define EMULTIHOP __WASI_ERRNO_MULTIHOP +#define EBADMSG __WASI_ERRNO_BADMSG +#define EOVERFLOW __WASI_ERRNO_OVERFLOW +#define EILSEQ __WASI_ERRNO_ILSEQ +#define ENOTSOCK __WASI_ERRNO_NOTSOCK +#define EDESTADDRREQ __WASI_ERRNO_DESTADDRREQ +#define EMSGSIZE __WASI_ERRNO_MSGSIZE +#define EPROTOTYPE __WASI_ERRNO_PROTOTYPE +#define ENOPROTOOPT __WASI_ERRNO_NOPROTOOPT +#define EPROTONOSUPPORT __WASI_ERRNO_PROTONOSUPPORT +#define EAFNOSUPPORT __WASI_ERRNO_AFNOSUPPORT +#define EADDRINUSE __WASI_ERRNO_ADDRINUSE +#define EADDRNOTAVAIL __WASI_ERRNO_ADDRNOTAVAIL +#define ENETDOWN __WASI_ERRNO_NETDOWN +#define ENETUNREACH __WASI_ERRNO_NETUNREACH +#define ENETRESET __WASI_ERRNO_NETRESET +#define ECONNABORTED __WASI_ERRNO_CONNABORTED +#define ECONNRESET __WASI_ERRNO_CONNRESET +#define ENOBUFS __WASI_ERRNO_NOBUFS +#define EISCONN __WASI_ERRNO_ISCONN +#define ENOTCONN __WASI_ERRNO_NOTCONN +#define ETIMEDOUT __WASI_ERRNO_TIMEDOUT +#define ECONNREFUSED __WASI_ERRNO_CONNREFUSED +#define EHOSTUNREACH __WASI_ERRNO_HOSTUNREACH +#define EALREADY __WASI_ERRNO_ALREADY +#define EINPROGRESS __WASI_ERRNO_INPROGRESS +#define ESTALE __WASI_ERRNO_STALE +#define EDQUOT __WASI_ERRNO_DQUOT +#define ECANCELED __WASI_ERRNO_CANCELED +#define EOWNERDEAD __WASI_ERRNO_OWNERDEAD +#define ENOTRECOVERABLE __WASI_ERRNO_NOTRECOVERABLE + +// Codes without a wasi equivalent, make sure they start +// above the wasi ones, which are dense [1,76]. +// Also try to fit the codes in a single byte signed wasm SLEB. + +#define ENOSTR 100 +#define EBFONT 101 +#define EBADSLT 102 +#define EBADRQC 103 +#define ENOANO 104 +#define ENOTBLK 105 +#define ECHRNG 106 +#define EL3HLT 107 +#define EL3RST 108 +#define ELNRNG 109 +#define EUNATCH 110 +#define ENOCSI 111 +#define EL2HLT 112 +#define EBADE 113 +#define EBADR 114 +#define EXFULL 115 +#define ENODATA 116 +#define ETIME 117 +#define ENOSR 118 +#define ENONET 119 +#define ENOPKG 120 +#define EREMOTE 121 +#define EADV 122 +#define ESRMNT 123 +#define ECOMM 124 +#define EDOTDOT 125 +#define ENOTUNIQ 126 +#define EBADFD 127 +#define EREMCHG 128 +#define ELIBACC 129 +#define ELIBBAD 130 +#define ELIBSCN 131 +#define ELIBMAX 132 +#define ELIBEXEC 133 +#define ERESTART 134 +#define ESTRPIPE 135 +#define EUSERS 136 +#define ESOCKTNOSUPPORT 137 +#define EOPNOTSUPP 138 +#define EPFNOSUPPORT 139 +#define ESHUTDOWN 140 +#define ETOOMANYREFS 141 +#define EHOSTDOWN 142 +#define EUCLEAN 143 +#define ENOTNAM 144 +#define ENAVAIL 145 +#define EISNAM 146 +#define EREMOTEIO 147 +#define ENOMEDIUM 148 +#define EMEDIUMTYPE 149 +#define ENOKEY 150 +#define EKEYEXPIRED 151 +#define EKEYREVOKED 152 +#define EKEYREJECTED 153 +#define ERFKILL 154 +#define EHWPOISON 155 +#define EL2NSYNC 156 + +// codes which musl defines as aliases + +#define EWOULDBLOCK EAGAIN +#define EDEADLOCK EDEADLK +#define ENOTSUP EOPNOTSUPP diff --git a/system/lib/libc/musl/arch/emscripten/bits/fenv.h b/system/lib/libc/musl/arch/emscripten/bits/fenv.h new file mode 100644 index 0000000000000..d3512cb6f7f53 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/fenv.h @@ -0,0 +1,27 @@ +#define FE_ALL_EXCEPT 0 + +#define FE_TONEAREST 0 +#define FE_DOWNWARD 0x400 +#define FE_UPWARD 0x800 +#define FE_TOWARDZERO 0xc00 + +typedef unsigned short fexcept_t; + +typedef struct { + unsigned short __control_word; + unsigned short __unused1; + unsigned short __status_word; + unsigned short __unused2; + unsigned short __tags; + unsigned short __unused3; + unsigned int __eip; + unsigned short __cs_selector; + unsigned int __opcode:11; + unsigned int __unused4:5; + unsigned int __data_offset; + unsigned short __data_selector; + unsigned short __unused5; + unsigned int __mxcsr; +} fenv_t; + +#define FE_DFL_ENV ((const fenv_t *) -1) diff --git a/system/lib/libc/musl/arch/emscripten/bits/float.h b/system/lib/libc/musl/arch/emscripten/bits/float.h new file mode 100644 index 0000000000000..53ec2d10876e6 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/float.h @@ -0,0 +1,17 @@ +#define FLT_ROUNDS 1 +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ + +#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ +#define LDBL_MIN __LDBL_MIN__ +#define LDBL_MAX __LDBL_MAX__ +#define LDBL_EPSILON __LDBL_EPSILON__ + +#define LDBL_MANT_DIG __LDBL_MANT_DIG__ +#define LDBL_MIN_EXP __LDBL_MIN_EXP__ +#define LDBL_MAX_EXP __LDBL_MAX_EXP__ + +#define LDBL_DIG __LDBL_DIG__ +#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ +#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ + +#define DECIMAL_DIG __DECIMAL_DIG__ diff --git a/system/lib/libc/musl/arch/emscripten/bits/limits.h b/system/lib/libc/musl/arch/emscripten/bits/limits.h new file mode 100644 index 0000000000000..7a09fdc1d175d --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/limits.h @@ -0,0 +1 @@ +#define PAGE_SIZE 65536 diff --git a/system/lib/libc/musl/arch/emscripten/bits/posix.h b/system/lib/libc/musl/arch/emscripten/bits/posix.h new file mode 100644 index 0000000000000..30a38714f36dd --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/posix.h @@ -0,0 +1,2 @@ +#define _POSIX_V6_ILP32_OFFBIG 1 +#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/system/lib/libc/musl/arch/emscripten/bits/reg.h b/system/lib/libc/musl/arch/emscripten/bits/reg.h new file mode 100644 index 0000000000000..1c4987c775f11 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/reg.h @@ -0,0 +1,6 @@ +#undef __WORDSIZE +#ifdef __wasm64__ +#define __WORDSIZE 64 +#else +#define __WORDSIZE 32 +#endif diff --git a/system/lib/libc/musl/arch/emscripten/bits/setjmp.h b/system/lib/libc/musl/arch/emscripten/bits/setjmp.h new file mode 100644 index 0000000000000..decd26dca07a0 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/setjmp.h @@ -0,0 +1 @@ +typedef unsigned long __jmp_buf[6]; diff --git a/system/lib/libc/musl/arch/emscripten/bits/signal.h b/system/lib/libc/musl/arch/emscripten/bits/signal.h new file mode 100644 index 0000000000000..58bc5e2c3a780 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/signal.h @@ -0,0 +1,123 @@ +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) + +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 +#endif + +#ifdef _GNU_SOURCE +#define REG_GS 0 +#define REG_FS 1 +#define REG_ES 2 +#define REG_DS 3 +#define REG_EDI 4 +#define REG_ESI 5 +#define REG_EBP 6 +#define REG_ESP 7 +#define REG_EBX 8 +#define REG_EDX 9 +#define REG_ECX 10 +#define REG_EAX 11 +#define REG_TRAPNO 12 +#define REG_ERR 13 +#define REG_EIP 14 +#define REG_CS 15 +#define REG_EFL 16 +#define REG_UESP 17 +#define REG_SS 18 +#endif + +struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +}; + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +typedef int greg_t, gregset_t[19]; +typedef struct _fpstate { + unsigned long cw, sw, tag, ipoff, cssel, dataoff, datasel; + struct { + unsigned short significand[4], exponent; + } _st[8]; + unsigned long status; +} *fpregset_t; +struct sigcontext { + unsigned short gs, __gsh, fs, __fsh, es, __esh, ds, __dsh; + unsigned long edi, esi, ebp, esp, ebx, edx, ecx, eax; + unsigned long trapno, err, eip; + unsigned short cs, __csh; + unsigned long eflags, esp_at_signal; + unsigned short ss, __ssh; + struct _fpstate *fpstate; + unsigned long oldmask, cr2; +}; +typedef struct { + gregset_t gregs; + fpregset_t fpregs; + unsigned long oldmask, cr2; +} mcontext_t; +#else +typedef struct { + unsigned __space[22]; +} mcontext_t; +#endif + +typedef struct __ucontext { + unsigned long uc_flags; + struct __ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + sigset_t uc_sigmask; + unsigned long __fpregs_mem[28]; +} ucontext_t; + +#define SA_NOCLDSTOP 1 +#define SA_NOCLDWAIT 2 +#define SA_SIGINFO 4 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 +#define SA_RESTORER 0x04000000 + +#endif + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT SIGABRT +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL 29 +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED SIGSYS + +#define _NSIG 65 + diff --git a/system/lib/libc/musl/arch/emscripten/bits/stat.h b/system/lib/libc/musl/arch/emscripten/bits/stat.h new file mode 100644 index 0000000000000..bfa9a597bcf6d --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/stat.h @@ -0,0 +1,26 @@ +/* copied from kernel definition, but with padding replaced + * by the corresponding correctly-sized userspace types. */ + +struct stat +{ + dev_t st_dev; +#ifndef __EMSCRIPTEN__ + int __st_dev_padding; + long __st_ino_truncated; +#endif + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; +#ifndef __EMSCRIPTEN__ + int __st_rdev_padding; +#endif + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + ino_t st_ino; +}; diff --git a/system/lib/libc/musl/arch/emscripten/bits/syscall.h b/system/lib/libc/musl/arch/emscripten/bits/syscall.h new file mode 100644 index 0000000000000..e3465a65c7406 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/syscall.h @@ -0,0 +1,89 @@ +#define SYS_chdir __syscall_chdir +#define SYS_chmod __syscall_chmod +#define SYS_getpid __syscall_getpid +#define SYS_pause __syscall_pause +#define SYS_sync __syscall_sync +#define SYS_rmdir __syscall_rmdir +#define SYS_dup __syscall_dup +#define SYS_acct __syscall_acct +#define SYS_ioctl __syscall_ioctl +#define SYS_setpgid __syscall_setpgid +#define SYS_umask __syscall_umask +#define SYS_getppid __syscall_getppid +#define SYS_setsid __syscall_setsid +#define SYS_getrusage __syscall_getrusage +#define SYS_munmap __syscall_munmap +#define SYS_fchmod __syscall_fchmod +#define SYS_getpriority __syscall_getpriority +#define SYS_setpriority __syscall_setpriority +#define SYS_wait4 __syscall_wait4 +#define SYS_setdomainname __syscall_setdomainname +#define SYS_uname __syscall_uname +#define SYS_mprotect __syscall_mprotect +#define SYS_getpgid __syscall_getpgid +#define SYS_fchdir __syscall_fchdir +#define SYS_msync __syscall_msync +#define SYS_getsid __syscall_getsid +#define SYS_fdatasync __syscall_fdatasync +#define SYS_mlock __syscall_mlock +#define SYS_munlock __syscall_munlock +#define SYS_mlockall __syscall_mlockall +#define SYS_munlockall __syscall_munlockall +#define SYS_mremap __syscall_mremap +#define SYS_poll __syscall_poll +#define SYS_getcwd __syscall_getcwd +#define SYS_mmap2 __syscall_mmap2 +#define SYS_truncate64 __syscall_truncate64 +#define SYS_ftruncate64 __syscall_ftruncate64 +#define SYS_stat64 __syscall_stat64 +#define SYS_lstat64 __syscall_lstat64 +#define SYS_fstat64 __syscall_fstat64 +#define SYS_getuid32 __syscall_getuid32 +#define SYS_getgid32 __syscall_getgid32 +#define SYS_geteuid32 __syscall_geteuid32 +#define SYS_getegid32 __syscall_getegid32 +#define SYS_getgroups32 __syscall_getgroups32 +#define SYS_fchown32 __syscall_fchown32 +#define SYS_getresuid32 __syscall_getresuid32 +#define SYS_getresgid32 __syscall_getresgid32 +#define SYS_mincore __syscall_mincore +#define SYS_madvise __syscall_madvise +#define SYS_getdents64 __syscall_getdents64 +#define SYS_fcntl64 __syscall_fcntl64 +#define SYS_statfs64 __syscall_statfs64 +#define SYS_fstatfs64 __syscall_fstatfs64 +#define SYS_fadvise64 __syscall_fadvise64 +#define SYS_openat __syscall_openat +#define SYS_mkdirat __syscall_mkdirat +#define SYS_mknodat __syscall_mknodat +#define SYS_fchownat __syscall_fchownat +#define SYS_newfstatat __syscall_newfstatat +#define SYS_unlinkat __syscall_unlinkat +#define SYS_renameat __syscall_renameat +#define SYS_linkat __syscall_linkat +#define SYS_symlinkat __syscall_symlinkat +#define SYS_readlinkat __syscall_readlinkat +#define SYS_fchmodat2 __syscall_fchmodat2 +#define SYS_faccessat __syscall_faccessat +#define SYS_utimensat __syscall_utimensat +#define SYS_fallocate __syscall_fallocate +#define SYS_dup3 __syscall_dup3 +#define SYS_pipe2 __syscall_pipe2 +#define SYS_recvmmsg __syscall_recvmmsg +#define SYS_prlimit64 __syscall_prlimit64 +#define SYS_sendmmsg __syscall_sendmmsg +#define SYS_socket __syscall_socket +#define SYS_socketpair __syscall_socketpair +#define SYS_bind __syscall_bind +#define SYS_connect __syscall_connect +#define SYS_listen __syscall_listen +#define SYS_accept4 __syscall_accept4 +#define SYS_getsockopt __syscall_getsockopt +#define SYS_setsockopt __syscall_setsockopt +#define SYS_getsockname __syscall_getsockname +#define SYS_getpeername __syscall_getpeername +#define SYS_sendto __syscall_sendto +#define SYS_sendmsg __syscall_sendmsg +#define SYS_recvfrom __syscall_recvfrom +#define SYS_recvmsg __syscall_recvmsg +#define SYS_shutdown __syscall_shutdown diff --git a/system/lib/libc/musl/arch/emscripten/bits/user.h b/system/lib/libc/musl/arch/emscripten/bits/user.h new file mode 100644 index 0000000000000..fa623621eeba3 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/user.h @@ -0,0 +1,48 @@ +#undef __WORDSIZE +#define __WORDSIZE 32 + +typedef struct user_fpregs_struct +{ + long cwd, swd, twd, fip, fcs, foo, fos, st_space[20]; +} elf_fpregset_t; + +typedef struct user_fpxregs_struct +{ + unsigned short cwd, swd, twd, fop; + long fip, fcs, foo, fos, mxcsr, reserved; + long st_space[32], xmm_space[32], padding[56]; +} elf_fpxregset_t; + +struct user_regs_struct +{ + long ebx, ecx, edx, esi, edi, ebp, eax, xds, xes, xfs, xgs; + long orig_eax, eip, xcs, eflags, esp, xss; +}; + +#define ELF_NGREG 17 +typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG]; + +struct user +{ + struct user_regs_struct regs; + int u_fpvalid; + struct user_fpregs_struct i387; + unsigned long u_tsize; + unsigned long u_dsize; + unsigned long u_ssize; + unsigned long start_code; + unsigned long start_stack; + long signal; + int reserved; + struct user_regs_struct *u_ar0; + struct user_fpregs_struct *u_fpstate; + unsigned long magic; + char u_comm[32]; + int u_debugreg[8]; +}; + +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) diff --git a/system/lib/libc/musl/arch/emscripten/crt_arch.h b/system/lib/libc/musl/arch/emscripten/crt_arch.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/system/lib/libc/musl/arch/emscripten/kstat.h b/system/lib/libc/musl/arch/emscripten/kstat.h new file mode 100644 index 0000000000000..72c5d0af803e6 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/kstat.h @@ -0,0 +1,3 @@ +#include + +#define kstat stat diff --git a/system/lib/libc/musl/arch/emscripten/pthread_arch.h b/system/lib/libc/musl/arch/emscripten/pthread_arch.h new file mode 100644 index 0000000000000..a62934a5d2214 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/pthread_arch.h @@ -0,0 +1,5 @@ +uintptr_t __get_tp(void); + +#define TP_ADJ(p) (p) + +#define CANCEL_REG_IP 16 diff --git a/system/lib/libc/musl/arch/emscripten/syscall_arch.h b/system/lib/libc/musl/arch/emscripten/syscall_arch.h new file mode 100644 index 0000000000000..cf9ad1048dc64 --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/syscall_arch.h @@ -0,0 +1,8 @@ +#include +#include +#include + +// Compile as if we can pass uint64 values directly to the host. Binaryen will +// take care of splitting any i64 params into a pair of i32 values if needed. +#define __SYSCALL_LL_E(x) (x) +#define __SYSCALL_LL_O(x) (x) diff --git a/system/lib/libc/musl/arch/generic/bits/stdarg.h b/system/lib/libc/musl/arch/generic/bits/stdarg.h new file mode 100644 index 0000000000000..fde378146d5df --- /dev/null +++ b/system/lib/libc/musl/arch/generic/bits/stdarg.h @@ -0,0 +1,4 @@ +#define va_start(v,l) __builtin_va_start(v,l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l) __builtin_va_arg(v,l) +#define va_copy(d,s) __builtin_va_copy(d,s) diff --git a/system/lib/libc/musl/config.mak b/system/lib/libc/musl/config.mak new file mode 100644 index 0000000000000..5b46fcdcdedec --- /dev/null +++ b/system/lib/libc/musl/config.mak @@ -0,0 +1,32 @@ +# This version of config.mak was generated by: +# ./configure +# Any changes made here will be lost if configure is re-run +AR = $(CROSS_COMPILE)ar +RANLIB = $(CROSS_COMPILE)ranlib +ARCH = x86_64 +SUBARCH = +ASMSUBARCH = +srcdir = . +prefix = /usr/local/musl +exec_prefix = $(prefix) +bindir = $(exec_prefix)/bin +libdir = $(prefix)/lib +includedir = $(prefix)/include +syslibdir = /lib +CC = gcc +CFLAGS = +CFLAGS_AUTO = -Os -pipe -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith +CFLAGS_C99FSE = -std=c99 -nostdinc -ffreestanding -fexcess-precision=standard -frounding-math -Wa,--noexecstack +CFLAGS_MEMOPS = -fno-tree-loop-distribute-patterns +CFLAGS_NOSSP = -fno-stack-protector +CPPFLAGS = +LDFLAGS = +LDFLAGS_AUTO = -Wl,--sort-section,alignment -Wl,--sort-common -Wl,--gc-sections -Wl,--hash-style=both -Wl,--no-undefined -Wl,--exclude-libs=ALL -Wl,--dynamic-list=./dynamic.list +CROSS_COMPILE = +LIBCC = -lgcc -lgcc_eh +OPTIMIZE_GLOBS = internal/*.c malloc/*.c string/*.c +ALL_TOOLS = obj/musl-gcc +TOOL_LIBS = lib/musl-gcc.specs +ADD_CFI = no +WRAPCC_GCC = $(CC) +AOBJS = $(LOBJS) diff --git a/system/lib/libc/musl/configure b/system/lib/libc/musl/configure index bc9fbe48cc443..13bda76840a31 100755 --- a/system/lib/libc/musl/configure +++ b/system/lib/libc/musl/configure @@ -405,7 +405,7 @@ tryflag CFLAGS_NOSSP -fno-stack-protector # option is sufficient, and if not, add a macro to cripple these # functions with volatile... # -tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns +# XXX EMSCRIPTEN tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns # # Enable debugging if requessted. @@ -546,7 +546,7 @@ tryflag CFLAGS_AUTO -Wno-pointer-to-int-cast # tryflag CFLAGS_AUTO -Werror=implicit-function-declaration tryflag CFLAGS_AUTO -Werror=implicit-int -tryflag CFLAGS_AUTO -Werror=pointer-sign +# XXX EMSCRIPTEN tryflag CFLAGS_AUTO -Werror=pointer-sign tryflag CFLAGS_AUTO -Werror=pointer-arith tryflag CFLAGS_AUTO -Werror=int-conversion tryflag CFLAGS_AUTO -Werror=incompatible-pointer-types diff --git a/system/lib/libc/musl/include/alltypes.h.in b/system/lib/libc/musl/include/alltypes.h.in index d47aeea9aa8b8..2da1da767eb97 100644 --- a/system/lib/libc/musl/include/alltypes.h.in +++ b/system/lib/libc/musl/include/alltypes.h.in @@ -12,17 +12,21 @@ TYPEDEF _Reg register_t; TYPEDEF _Int64 time_t; TYPEDEF _Int64 suseconds_t; -TYPEDEF signed char int8_t; -TYPEDEF signed short int16_t; -TYPEDEF signed int int32_t; -TYPEDEF signed _Int64 int64_t; -TYPEDEF signed _Int64 intmax_t; -TYPEDEF unsigned char uint8_t; -TYPEDEF unsigned short uint16_t; -TYPEDEF unsigned int uint32_t; -TYPEDEF unsigned _Int64 uint64_t; -TYPEDEF unsigned _Int64 u_int64_t; -TYPEDEF unsigned _Int64 uintmax_t; +// XXX EMSCRIPTEN: This file has been modified from the upstream musl version +// to make use of clang pre-defined macros whereever possible, eliminating +// possible inconsistencies. + +TYPEDEF __INT8_TYPE__ int8_t; +TYPEDEF __INT16_TYPE__ int16_t; +TYPEDEF __INT32_TYPE__ int32_t; +TYPEDEF __INT64_TYPE__ int64_t; +TYPEDEF __INTMAX_TYPE__ intmax_t; +TYPEDEF __UINT8_TYPE__ uint8_t; +TYPEDEF __UINT16_TYPE__ uint16_t; +TYPEDEF __UINT32_TYPE__ uint32_t; +TYPEDEF __UINT64_TYPE__ uint64_t; +TYPEDEF __UINT64_TYPE__ u_int64_t; +TYPEDEF __UINTMAX_TYPE__ uintmax_t; TYPEDEF unsigned mode_t; TYPEDEF unsigned _Reg nlink_t; @@ -73,7 +77,14 @@ TYPEDEF struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; TYPEDEF struct __locale_struct * locale_t; -TYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t; +// Musl uses 128 bytes for sigset_t, presumably for some kind of ABI +// compatability with the kernel or GLIBC, but in emscripten we can be precise. +// Since we have _NSIG = 65 which only need 2 `long`s for the bitmask. +// The signals we support are +// 1 - 31 - standard POSIX signals (see emscripten/bits/signal.h) +// 32 - 34 - pthread-specific signals (see pthread_impl.h> +// 35 - 65 - user-defined RT signals (we don't currently have any test coverage of these). +TYPEDEF struct __sigset_t { unsigned long __bits[2]; } sigset_t; STRUCT iovec { void *iov_base; size_t iov_len; }; diff --git a/system/lib/libc/musl/include/fcntl.h b/system/lib/libc/musl/include/fcntl.h index 53f98a8bed98a..cce43031f112d 100644 --- a/system/lib/libc/musl/include/fcntl.h +++ b/system/lib/libc/musl/include/fcntl.h @@ -1,6 +1,10 @@ #ifndef _FCNTL_H #define _FCNTL_H +#ifdef __EMSCRIPTEN__ +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -75,9 +79,15 @@ int posix_fallocate(int, off_t, off_t); #undef SEEK_SET #undef SEEK_CUR #undef SEEK_END +#ifdef __EMSCRIPTEN__ +#define SEEK_SET __WASI_WHENCE_SET +#define SEEK_CUR __WASI_WHENCE_CUR +#define SEEK_END __WASI_WHENCE_END +#else #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 +#endif // EMSCRIPTEN #ifndef S_IRUSR #define S_ISUID 04000 diff --git a/system/lib/libc/musl/include/features.h b/system/lib/libc/musl/include/features.h index 85cfb72a0d427..952ffd968592b 100644 --- a/system/lib/libc/musl/include/features.h +++ b/system/lib/libc/musl/include/features.h @@ -16,6 +16,13 @@ #define _XOPEN_SOURCE 700 #endif +#if defined(__EMSCRIPTEN__) && defined(_GNU_SOURCE) +// In emscripten the LFS functions are kept around when _GNU_SOURCE is +// defined, for increased compatabiliy. This is also what glibc does. +#undef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE 1 +#endif + #if __STDC_VERSION__ >= 199901L #define __restrict restrict #elif !defined(__GNUC__) diff --git a/system/lib/libc/musl/include/inttypes.h b/system/lib/libc/musl/include/inttypes.h index 61dcb72731f0d..90c35c8664ae8 100644 --- a/system/lib/libc/musl/include/inttypes.h +++ b/system/lib/libc/musl/include/inttypes.h @@ -22,7 +22,12 @@ uintmax_t strtoumax(const char *__restrict, char **__restrict, int); intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int); uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); -#if UINTPTR_MAX == UINT64_MAX +#if defined(__EMSCRIPTEN__) +// Under emscripten __PTRDIFF_TYPE__ and therefor intptr_t are defined to +// be `long int` even on wasm32. +#define __PRI64 "ll" +#define __PRIPTR "l" +#elif UINTPTR_MAX == UINT64_MAX #define __PRI64 "l" #define __PRIPTR "l" #else diff --git a/system/lib/libc/musl/include/limits.h b/system/lib/libc/musl/include/limits.h index 53a27b9de43fa..a1365cfc15e22 100644 --- a/system/lib/libc/musl/include/limits.h +++ b/system/lib/libc/musl/include/limits.h @@ -51,7 +51,14 @@ #define SYMLOOP_MAX 40 #define WORD_BIT 32 #define SSIZE_MAX LONG_MAX +#ifdef __EMSCRIPTEN__ +// We depend on the JS API to reteive the local name for the current +// timezone and this can sometimes exceed 6 chars. For example: +// TZ='Asia/Kathmandu' yields 'GMT+5:45'. +#define TZNAME_MAX 16 +#else #define TZNAME_MAX 6 +#endif #define TTY_NAME_MAX 32 #define HOST_NAME_MAX 255 diff --git a/system/lib/libc/musl/include/locale.h b/system/lib/libc/musl/include/locale.h index 11106fea878a6..624547f6c3e39 100644 --- a/system/lib/libc/musl/include/locale.h +++ b/system/lib/libc/musl/include/locale.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/setjmp.h b/system/lib/libc/musl/include/setjmp.h index 1976af231b8c4..af72c80cdbce0 100644 --- a/system/lib/libc/musl/include/setjmp.h +++ b/system/lib/libc/musl/include/setjmp.h @@ -25,9 +25,15 @@ typedef struct __jmp_buf_tag { || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) typedef jmp_buf sigjmp_buf; +/* XXX EMSCRIPTEN: No signals support, alias sigsetjmp and siglongjmp to their non-signals counterparts. */ +#if __EMSCRIPTEN__ && !defined(LLVM_LIBC) +#define sigsetjmp(buf, x) setjmp((buf)) +#define siglongjmp(buf, val) longjmp(buf, val) +#else int sigsetjmp (sigjmp_buf, int) __setjmp_attr; _Noreturn void siglongjmp (sigjmp_buf, int); #endif +#endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) diff --git a/system/lib/libc/musl/include/signal.h b/system/lib/libc/musl/include/signal.h index c347f8610a3f2..e75cb860a3f6d 100644 --- a/system/lib/libc/musl/include/signal.h +++ b/system/lib/libc/musl/include/signal.h @@ -282,7 +282,7 @@ int sigandset(sigset_t *, const sigset_t *, const sigset_t *); #define SIG_ERR ((void (*)(int))-1) #define SIG_DFL ((void (*)(int)) 0) -#define SIG_IGN ((void (*)(int)) 1) +#define SIG_IGN ((void (*)(int))-2) /* XXX EMSCRIPTEN: use -2 since 1 is a valid function address */ typedef int sig_atomic_t; diff --git a/system/lib/libc/musl/include/stddef.h b/system/lib/libc/musl/include/stddef.h index f25b86396e80a..5fa18390a80b0 100644 --- a/system/lib/libc/musl/include/stddef.h +++ b/system/lib/libc/musl/include/stddef.h @@ -1,7 +1,7 @@ #ifndef _STDDEF_H #define _STDDEF_H -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/stdint.h b/system/lib/libc/musl/include/stdint.h index a2968197dbe23..8239d4703523a 100644 --- a/system/lib/libc/musl/include/stdint.h +++ b/system/lib/libc/musl/include/stdint.h @@ -19,99 +19,104 @@ #include -typedef int8_t int_fast8_t; -typedef int64_t int_fast64_t; - -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; - -typedef uint8_t uint_fast8_t; -typedef uint64_t uint_fast64_t; - -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -#define INT8_MIN (-1-0x7f) -#define INT16_MIN (-1-0x7fff) -#define INT32_MIN (-1-0x7fffffff) -#define INT64_MIN (-1-0x7fffffffffffffff) - -#define INT8_MAX (0x7f) -#define INT16_MAX (0x7fff) -#define INT32_MAX (0x7fffffff) -#define INT64_MAX (0x7fffffffffffffff) - -#define UINT8_MAX (0xff) -#define UINT16_MAX (0xffff) -#define UINT32_MAX (0xffffffffu) -#define UINT64_MAX (0xffffffffffffffffu) - -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST64_MIN INT64_MIN - -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST64_MIN INT64_MIN - -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST64_MAX INT64_MAX - -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MAX INT64_MAX - -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST64_MAX UINT64_MAX - -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -#define WINT_MIN 0U -#define WINT_MAX UINT32_MAX - -#if L'\0'-1 > 0 -#define WCHAR_MAX (0xffffffffu+L'\0') -#define WCHAR_MIN (0+L'\0') -#else -#define WCHAR_MAX (0x7fffffff+L'\0') -#define WCHAR_MIN (-1-0x7fffffff+L'\0') -#endif +// XXX EMSCRIPTEN: This file has been modified from the upstream musl version +// to make use of clang pre-defined macros whereever possible, eliminating +// possible inconsistencies. + +typedef __INT_FAST8_TYPE__ int_fast8_t; +typedef __INT_FAST16_TYPE__ int_fast16_t; +typedef __INT_FAST32_TYPE__ int_fast32_t; +typedef __INT_FAST64_TYPE__ int_fast64_t; + +typedef __INT_LEAST8_TYPE__ int_least8_t; +typedef __INT_LEAST16_TYPE__ int_least16_t; +typedef __INT_LEAST32_TYPE__ int_least32_t; +typedef __INT_LEAST64_TYPE__ int_least64_t; + +typedef __UINT_FAST8_TYPE__ uint_fast8_t; +typedef __UINT_FAST16_TYPE__ uint_fast16_t; +typedef __UINT_FAST32_TYPE__ uint_fast32_t; +typedef __UINT_FAST64_TYPE__ uint_fast64_t; + +typedef __UINT_LEAST8_TYPE__ uint_least8_t; +typedef __UINT_LEAST16_TYPE__ uint_least16_t; +typedef __UINT_LEAST32_TYPE__ uint_least32_t; +typedef __UINT_LEAST64_TYPE__ uint_least64_t; + +#define INT8_MIN (-1-__INT8_MAX__) +#define INT16_MIN (-1-__INT16_MAX__) +#define INT32_MIN (-1-__INT32_MAX__) +#define INT64_MIN (-1-__INT64_MAX__) + +#define INT8_MAX __INT8_MAX__ +#define INT16_MAX __INT16_MAX__ +#define INT32_MAX __INT32_MAX__ +#define INT64_MAX __INT64_MAX__ + +#define UINT8_MAX __UINT8_MAX__ +#define UINT16_MAX __UINT16_MAX__ +#define UINT32_MAX __UINT32_MAX__ +#define UINT64_MAX __UINT64_MAX__ + +#define INT_FAST8_MIN (-1-__INT_FAST8_MAX__) +#define INT_FAST16_MIN (-1-__INT_FAST16_MAX__) +#define INT_FAST32_MIN (-1-__INT_FAST32_MAX__) +#define INT_FAST64_MIN (-1-__INT_FAST64_MAX__) + +#define INT_LEAST8_MIN (-1-__INT_LEAST8_MAX__) +#define INT_LEAST16_MIN (-1-__INT_LEAST16_MAX__) +#define INT_LEAST32_MIN (-1-__INT_LEAST32_MAX__) +#define INT_LEAST64_MIN (-1-__INT_LEAST64_MAX__) + +#define INT_FAST8_MAX __INT_FAST8_MAX__ +#define INT_FAST16_MAX __INT_FAST16_MAX__ +#define INT_FAST32_MAX __INT_FAST32_MAX__ +#define INT_FAST64_MAX __INT_FAST64_MAX__ + +#define INT_LEAST8_MAX __INT_LEAST8_MAX__ +#define INT_LEAST16_MAX __INT_LEAST16_MAX__ +#define INT_LEAST32_MAX __INT_LEAST32_MAX__ +#define INT_LEAST64_MAX __INT_LEAST64_MAX__ + +#define UINT_FAST8_MAX __UINT_FAST8_MAX__ +#define UINT_FAST16_MAX __UINT_FAST16_MAX__ +#define UINT_FAST32_MAX __UINT_FAST32_MAX__ +#define UINT_FAST64_MAX __UINT_FAST64_MAX__ + +#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__ +#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__ +#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__ +#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__ + +#define INTMAX_MIN (-1-__INTMAX_MAX__) +#define INTMAX_MAX __INTMAX_MAX__ +#define UINTMAX_MAX __UINTMAX_MAX__ + +#define WCHAR_MAX __WCHAR_MAX__ +#define WINT_MAX __WINT_MAX__ +#define INTPTR_MAX __INTPTR_MAX__ +#define UINTPTR_MAX __UINTPTR_MAX__ +#define PTRDIFF_MAX __PTRDIFF_MAX__ +#define SIZE_MAX __SIZE_MAX__ + +#define WINT_MIN (-1-__WINT_MAX__) +#define WCHAR_MIN (-1-__WCHAR_MAX__) +#define INTPTR_MIN (-1-__INTPTR_MAX__) +#define PTRDIFF_MIN (-1-__PTRDIFF_MAX__) #define SIG_ATOMIC_MIN INT32_MIN #define SIG_ATOMIC_MAX INT32_MAX -#include - -#define INT8_C(c) c -#define INT16_C(c) c -#define INT32_C(c) c - -#define UINT8_C(c) c -#define UINT16_C(c) c -#define UINT32_C(c) c ## U - -#if UINTPTR_MAX == UINT64_MAX -#define INT64_C(c) c ## L -#define UINT64_C(c) c ## UL -#define INTMAX_C(c) c ## L -#define UINTMAX_C(c) c ## UL -#else -#define INT64_C(c) c ## LL -#define UINT64_C(c) c ## ULL -#define INTMAX_C(c) c ## LL -#define UINTMAX_C(c) c ## ULL -#endif +#define INT8_C __INT8_C +#define INT16_C __INT16_C +#define INT32_C __INT32_C +#define INT64_C __INT64_C +#define INTMAX_C __INTMAX_C + +#define UINT8_C __UINT8_C +#define UINT16_C __UINT16_C +#define UINT32_C __UINT32_C +#define UINT64_C __UINT64_C +#define UINTMAX_C __UINTMAX_C #endif diff --git a/system/lib/libc/musl/include/stdio.h b/system/lib/libc/musl/include/stdio.h index 4ea4c17077a3b..2449b02055c89 100644 --- a/system/lib/libc/musl/include/stdio.h +++ b/system/lib/libc/musl/include/stdio.h @@ -1,6 +1,10 @@ #ifndef _STDIO_H #define _STDIO_H +#ifdef __EMSCRIPTEN__ +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -25,7 +29,7 @@ extern "C" { #include -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L @@ -39,9 +43,15 @@ extern "C" { #undef SEEK_SET #undef SEEK_CUR #undef SEEK_END +#ifdef __EMSCRIPTEN__ +#define SEEK_SET __WASI_WHENCE_SET +#define SEEK_CUR __WASI_WHENCE_CUR +#define SEEK_END __WASI_WHENCE_END +#else #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 +#endif // EMSCRIPTEN #define _IOFBF 0 #define _IOLBF 1 diff --git a/system/lib/libc/musl/include/stdlib.h b/system/lib/libc/musl/include/stdlib.h index 475190bfa2c9f..efbd0b55a99e2 100644 --- a/system/lib/libc/musl/include/stdlib.h +++ b/system/lib/libc/musl/include/stdlib.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/string.h b/system/lib/libc/musl/include/string.h index 83e2b946486f6..874680c563b2c 100644 --- a/system/lib/libc/musl/include/string.h +++ b/system/lib/libc/musl/include/string.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/time.h b/system/lib/libc/musl/include/time.h index 3d94837205ad5..a91e1f76b4a44 100644 --- a/system/lib/libc/musl/include/time.h +++ b/system/lib/libc/musl/include/time.h @@ -7,7 +7,7 @@ extern "C" { #include -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/include/unistd.h b/system/lib/libc/musl/include/unistd.h index 42b0e82bd9e7b..59b38fd01d8a0 100644 --- a/system/lib/libc/musl/include/unistd.h +++ b/system/lib/libc/musl/include/unistd.h @@ -1,6 +1,10 @@ #ifndef _UNISTD_H #define _UNISTD_H +#ifdef __EMSCRIPTEN__ +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -11,13 +15,19 @@ extern "C" { #define STDOUT_FILENO 1 #define STDERR_FILENO 2 +#ifdef __EMSCRIPTEN__ +#define SEEK_SET __WASI_WHENCE_SET +#define SEEK_CUR __WASI_WHENCE_CUR +#define SEEK_END __WASI_WHENCE_END +#else #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 #define SEEK_DATA 3 #define SEEK_HOLE 4 +#endif // EMSCRIPTEN -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L @@ -177,7 +187,7 @@ void setusershell(void); void endusershell(void); char *getusershell(void); int acct(const char *); -long syscall(long, ...); +/* XXX EMSCRIPTEN long syscall(long, ...); */ int execvpe(const char *, char *const [], char *const []); int issetugid(void); int getentropy(void *, size_t); @@ -229,20 +239,44 @@ pid_t gettid(void); #define _POSIX_FSYNC _POSIX_VERSION #define _POSIX_NO_TRUNC 1 #define _POSIX_RAW_SOCKETS _POSIX_VERSION + +#ifndef __EMSCRIPTEN__ #define _POSIX_REALTIME_SIGNALS _POSIX_VERSION +#else +#define _POSIX_REALTIME_SIGNALS -1 +#endif + #define _POSIX_REGEXP 1 #define _POSIX_SAVED_IDS 1 #define _POSIX_SHELL 1 + +#ifndef __EMSCRIPTEN__ #define _POSIX_SPAWN _POSIX_VERSION +#else +#define _POSIX_SPAWN -1 +#endif + #define _POSIX_VDISABLE 0 +#if defined(__EMSCRIPTEN__) && !defined(_REENTRANT) /* XXX Emscripten doesn't always support pthreads */ +#define _POSIX_THREADS -1 +#else #define _POSIX_THREADS _POSIX_VERSION +#endif +#ifndef __EMSCRIPTEN__ #define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION +#else +#define _POSIX_THREAD_PROCESS_SHARED -1 +#endif #define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION #define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION #define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION #define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION +#ifdef __EMSCRIPTEN__ +#define _POSIX_THREAD_CPUTIME -1 +#else #define _POSIX_THREAD_CPUTIME _POSIX_VERSION +#endif #define _POSIX_TIMERS _POSIX_VERSION #define _POSIX_TIMEOUTS _POSIX_VERSION #define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION @@ -253,7 +287,9 @@ pid_t gettid(void); #define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION #define _POSIX_ASYNCHRONOUS_IO _POSIX_VERSION #define _POSIX_SEMAPHORES _POSIX_VERSION +#ifndef __EMSCRIPTEN__ #define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION +#endif #define _POSIX2_C_BIND _POSIX_VERSION diff --git a/system/lib/libc/musl/include/wchar.h b/system/lib/libc/musl/include/wchar.h index ed5d774dfa968..18eee67ca6c66 100644 --- a/system/lib/libc/musl/include/wchar.h +++ b/system/lib/libc/musl/include/wchar.h @@ -38,7 +38,7 @@ extern "C" { #define WCHAR_MIN (-1-0x7fffffff+L'\0') #endif -#if __cplusplus >= 201103L +#if __cplusplus >= 201103L && !defined(__EMSCRIPTEN__) #define NULL nullptr #elif defined(__cplusplus) #define NULL 0L diff --git a/system/lib/libc/musl/src/conf/confstr.c b/system/lib/libc/musl/src/conf/confstr.c index 3d4172846dba9..9c12d365babf2 100644 --- a/system/lib/libc/musl/src/conf/confstr.c +++ b/system/lib/libc/musl/src/conf/confstr.c @@ -6,7 +6,26 @@ size_t confstr(int name, char *buf, size_t len) { const char *s = ""; if (!name) { +#ifndef __EMSCRIPTEN__ s = "/bin:/usr/bin"; +#else + // TODO(sbc): Can we just remove these custom values. + // We have tests that check for them but its not clear + // anything else does. + s = "/"; + } else if (name == _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS) { + s = "POSIX_V6_ILP32_OFF32\nPOSIX_V6_ILP32_OFFBIG"; + } else if (name == _CS_GNU_LIBPTHREAD_VERSION) { + s = ""; + } else if (name == _CS_GNU_LIBC_VERSION) { + s = "glibc 2.14"; + } else if (name == _CS_POSIX_V6_ILP32_OFF32_CFLAGS || + name == _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS || + name == _CS_POSIX_V6_ILP32_OFF32_LDFLAGS) { + s = "-m32"; + } else if (name == _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS) { + s = "-m32 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"; +#endif } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>35U) { errno = EINVAL; return 0; diff --git a/system/lib/libc/musl/src/conf/fpathconf.c b/system/lib/libc/musl/src/conf/fpathconf.c index e6aca5cffe6f7..3161c76ffcab4 100644 --- a/system/lib/libc/musl/src/conf/fpathconf.c +++ b/system/lib/libc/musl/src/conf/fpathconf.c @@ -24,7 +24,7 @@ long fpathconf(int fd, int name) [_PC_REC_MIN_XFER_SIZE] = 4096, [_PC_REC_XFER_ALIGN] = 4096, [_PC_ALLOC_SIZE_MIN] = 4096, - [_PC_SYMLINK_MAX] = -1, + [_PC_SYMLINK_MAX] = 255, // XXX EMSCRIPTEN replace -1 [_PC_2_SYMLINKS] = 1 }; if (name >= sizeof(values)/sizeof(values[0])) { diff --git a/system/lib/libc/musl/src/conf/sysconf.c b/system/lib/libc/musl/src/conf/sysconf.c index 8dd5c725031dd..f3f9993977d47 100644 --- a/system/lib/libc/musl/src/conf/sysconf.c +++ b/system/lib/libc/musl/src/conf/sysconf.c @@ -4,10 +4,17 @@ #include #include #include +#ifndef __EMSCRIPTEN__ #include +#endif #include "syscall.h" #include "libc.h" +#ifdef __EMSCRIPTEN__ +#include "emscripten/heap.h" +#include "emscripten/threading.h" +#endif + #define JT(x) (-256|(x)) #define VER JT(1) #define JT_ARG_MAX JT(2) @@ -29,15 +36,15 @@ long sysconf(int name) { static const short values[] = { [_SC_ARG_MAX] = JT_ARG_MAX, - [_SC_CHILD_MAX] = RLIM(NPROC), + [_SC_CHILD_MAX] = 1024, // XXX EMSCRIPTEN replace RLIM(NPROC), [_SC_CLK_TCK] = 100, [_SC_NGROUPS_MAX] = 32, - [_SC_OPEN_MAX] = RLIM(NOFILE), + [_SC_OPEN_MAX] = 1024, // XXX EMSCRIPTEN replace RLIM(NOFILE), [_SC_STREAM_MAX] = -1, [_SC_TZNAME_MAX] = TZNAME_MAX, [_SC_JOB_CONTROL] = 1, [_SC_SAVED_IDS] = 1, - [_SC_REALTIME_SIGNALS] = VER, + [_SC_REALTIME_SIGNALS] = 1, [_SC_PRIORITY_SCHEDULING] = -1, [_SC_TIMERS] = VER, [_SC_ASYNCHRONOUS_IO] = VER, @@ -54,7 +61,7 @@ long sysconf(int name) [_SC_AIO_LISTIO_MAX] = -1, [_SC_AIO_MAX] = -1, [_SC_AIO_PRIO_DELTA_MAX] = JT_ZERO, /* ?? */ - [_SC_DELAYTIMER_MAX] = JT_DELAYTIMER_MAX, + [_SC_DELAYTIMER_MAX] = _POSIX_DELAYTIMER_MAX, [_SC_MQ_OPEN_MAX] = -1, [_SC_MQ_PRIO_MAX] = JT_MQ_PRIO_MAX, [_SC_VERSION] = VER, @@ -92,10 +99,10 @@ long sysconf(int name) [_SC_THREAD_THREADS_MAX] = -1, [_SC_THREAD_ATTR_STACKADDR] = VER, [_SC_THREAD_ATTR_STACKSIZE] = VER, - [_SC_THREAD_PRIORITY_SCHEDULING] = VER, + [_SC_THREAD_PRIORITY_SCHEDULING] = -1, // XXX EMSCRIPTEN replace VER, [_SC_THREAD_PRIO_INHERIT] = -1, [_SC_THREAD_PRIO_PROTECT] = -1, - [_SC_THREAD_PROCESS_SHARED] = VER, + [_SC_THREAD_PROCESS_SHARED] = -1, // XXX EMSCRIPTEN replace VER, [_SC_NPROCESSORS_CONF] = JT_NPROCESSORS_CONF, [_SC_NPROCESSORS_ONLN] = JT_NPROCESSORS_ONLN, [_SC_PHYS_PAGES] = JT_PHYS_PAGES, @@ -115,8 +122,8 @@ long sysconf(int name) [_SC_XOPEN_XPG4] = -1, [_SC_NZERO] = NZERO, [_SC_XBS5_ILP32_OFF32] = -1, - [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, - [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, + [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, + [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, [_SC_XBS5_LPBIG_OFFBIG] = -1, [_SC_XOPEN_LEGACY] = -1, [_SC_XOPEN_REALTIME] = -1, @@ -145,8 +152,8 @@ long sysconf(int name) [_SC_STREAMS] = JT_ZERO, [_SC_2_PBS_CHECKPOINT] = -1, [_SC_V6_ILP32_OFF32] = -1, - [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1, - [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : -1, + [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO, + [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO, [_SC_V6_LPBIG_OFFBIG] = -1, [_SC_HOST_NAME_MAX] = HOST_NAME_MAX, [_SC_TRACE] = -1, @@ -201,14 +208,21 @@ long sysconf(int name) return DELAYTIMER_MAX; case JT_NPROCESSORS_CONF & 255: case JT_NPROCESSORS_ONLN & 255: ; +#ifdef __EMSCRIPTEN__ + return emscripten_num_logical_cores(); +#else unsigned char set[128] = {1}; int i, cnt; __syscall(SYS_sched_getaffinity, 0, sizeof set, set); for (i=cnt=0; ifd = fd; diff --git a/system/lib/libc/musl/src/env/__environ.c b/system/lib/libc/musl/src/env/__environ.c index fe8abcf9906a1..fcc881be0da8b 100644 --- a/system/lib/libc/musl/src/env/__environ.c +++ b/system/lib/libc/musl/src/env/__environ.c @@ -4,3 +4,40 @@ char **__environ = 0; weak_alias(__environ, ___environ); weak_alias(__environ, _environ); weak_alias(__environ, environ); + +#ifdef __EMSCRIPTEN__ +#include +#include +#include + +// We use emscripten_builtin_malloc here because this memory is never freed and +// and we don't want LSan to consider this a leak. +__attribute__((constructor(100))) // construct this before user code +void __emscripten_environ_constructor(void) { + size_t environ_count; + size_t environ_buf_size; + __wasi_errno_t err = __wasi_environ_sizes_get(&environ_count, + &environ_buf_size); + if (err != __WASI_ERRNO_SUCCESS) { + return; + } + + __environ = emscripten_builtin_malloc(sizeof(char *) * (environ_count + 1)); + if (__environ == 0) { + return; + } + char *environ_buf = emscripten_builtin_malloc(sizeof(char) * environ_buf_size); + if (environ_buf == 0) { + __environ = 0; + return; + } + + // Ensure null termination. + __environ[environ_count] = 0; + + err = __wasi_environ_get((uint8_t**)__environ, environ_buf); + if (err != __WASI_ERRNO_SUCCESS) { + __environ = 0; + } +} +#endif diff --git a/system/lib/libc/musl/src/env/__stack_chk_fail.c b/system/lib/libc/musl/src/env/__stack_chk_fail.c index e53526020f751..94d8e1d4c9604 100644 --- a/system/lib/libc/musl/src/env/__stack_chk_fail.c +++ b/system/lib/libc/musl/src/env/__stack_chk_fail.c @@ -23,6 +23,11 @@ void __init_ssp(void *entropy) void __stack_chk_fail(void) { +#if defined(__EMSCRIPTEN__) && !defined(NDEBUG) + // Report the reason for the crash, at least in debug builds. + // This is the same message that glibc outputs (even in release builds). + emscripten_err("*** stack smashing detected ***"); +#endif a_crash(); } diff --git a/system/lib/libc/musl/src/errno/__errno_location.c b/system/lib/libc/musl/src/errno/__errno_location.c index 7f9d6027a276a..458941368856a 100644 --- a/system/lib/libc/musl/src/errno/__errno_location.c +++ b/system/lib/libc/musl/src/errno/__errno_location.c @@ -1,9 +1,20 @@ #include #include "pthread_impl.h" +#ifdef __EMSCRIPTEN__ +// For emscripten we use TLS here instead of `__pthread_self`, so that in single +// threaded builds this gets lowered away to normal global variable. +// This also works for WASM_WORKERS there `__pthread_self` does not work. +static _Thread_local int __errno_storage = 0; +#endif + int *__errno_location(void) { +#ifdef __EMSCRIPTEN__ + return &__errno_storage; +#else return &__pthread_self()->errno_val; +#endif } weak_alias(__errno_location, ___errno_location); diff --git a/system/lib/libc/musl/src/errno/__strerror.h b/system/lib/libc/musl/src/errno/__strerror.h index 0398b5b6d5404..d9fd210fc30dc 100644 --- a/system/lib/libc/musl/src/errno/__strerror.h +++ b/system/lib/libc/musl/src/errno/__strerror.h @@ -2,8 +2,14 @@ * This file is included multiple times to declare and define a structure * with these messages, and then to define a lookup table translating * error codes to offsets of corresponding fields in the structure. */ - +#if defined(__EMSCRIPTEN__) +/* Error handling is introduced to match the behavior in llvm-libc. + * When invalid errno is specified, Unknown error: errno_code is emitted. + */ +E(0, "Success") +#else E(0, "No error information") +#endif E(EILSEQ, "Illegal byte sequence") E(EDOM, "Domain error") @@ -16,7 +22,12 @@ E(ENOENT, "No such file or directory") E(ESRCH, "No such process") E(EEXIST, "File exists") +#if defined(__EMSCRIPTEN__) +// This is intended to match the errno in llvm-libc. +E(EOVERFLOW, "Value too large for defined data type") +#else E(EOVERFLOW, "Value too large for data type") +#endif E(ENOSPC, "No space left on device") E(ENOMEM, "Out of memory") @@ -62,7 +73,11 @@ E(ENOLCK, "No locks available") E(EDEADLK, "Resource deadlock would occur") E(ENOTRECOVERABLE, "State not recoverable") +#if defined(__EMSCRIPTEN__) +E(EOWNERDEAD, "Owner died") +#else E(EOWNERDEAD, "Previous owner died") +#endif E(ECANCELED, "Operation canceled") E(ENOSYS, "Function not implemented") E(ENOMSG, "No message of desired type") diff --git a/system/lib/libc/musl/src/errno/strerror.c b/system/lib/libc/musl/src/errno/strerror.c index 7f926432b3090..0fd1c84289a2e 100644 --- a/system/lib/libc/musl/src/errno/strerror.c +++ b/system/lib/libc/musl/src/errno/strerror.c @@ -34,14 +34,30 @@ char *__strerror_l(int e, locale_t loc) if (e==EDQUOT) e=0; else if (e==EDQUOT_ORIG) e=EDQUOT; #endif +#ifdef __EMSCRIPTEN__ + if (e < 0 || e >= sizeof errmsgidx / sizeof *errmsgidx || (e != 0 && !errmsgidx[e])) { + return "Unknown error"; + } + s = (char *)&errmsgstr + errmsgidx[e]; + // strerror is a (debug) dependency of many emscripten syscalls which mean it + // must be excluded from LTO, along with all of its dependencies. + // In order to limit the transitive dependencies we disable localization of + // rrno messages here. + return (char *)s; +#else if (e >= sizeof errmsgidx / sizeof *errmsgidx) e = 0; s = (char *)&errmsgstr + errmsgidx[e]; return (char *)LCTRANS(s, LC_MESSAGES, loc); +#endif } char *strerror(int e) { +#ifdef __EMSCRIPTEN__ + return __strerror_l(e, NULL); +#else return __strerror_l(e, CURRENT_LOCALE); +#endif } weak_alias(__strerror_l, strerror_l); diff --git a/system/lib/libc/musl/src/exit/_Exit.c b/system/lib/libc/musl/src/exit/_Exit.c index 7a6115c7bbc71..9d06aac1d89ef 100644 --- a/system/lib/libc/musl/src/exit/_Exit.c +++ b/system/lib/libc/musl/src/exit/_Exit.c @@ -3,6 +3,10 @@ _Noreturn void _Exit(int ec) { +#ifdef __EMSCRIPTEN__ + __wasi_proc_exit(ec); +#else __syscall(SYS_exit_group, ec); for (;;) __syscall(SYS_exit, ec); +#endif } diff --git a/system/lib/libc/musl/src/exit/abort.c b/system/lib/libc/musl/src/exit/abort.c index f21f458eca149..a6427d51d66e9 100644 --- a/system/lib/libc/musl/src/exit/abort.c +++ b/system/lib/libc/musl/src/exit/abort.c @@ -6,8 +6,20 @@ #include "lock.h" #include "ksigaction.h" +#if __EMSCRIPTEN__ +#include "emscripten_internal.h" +#endif + _Noreturn void abort(void) { +#if __EMSCRIPTEN__ + /* In emscripten we call out to JS to perform the actual abort where it can + * produce a nice error. + * Note that the JS library function is not called `abort` to avoid conflict + * with the JavaScript abort helper (which takes a JS string as an argument + * and is itself used to implement `_abort_js`) */ + _abort_js(); +#else raise(SIGABRT); /* If there was a SIGABRT handler installed and it returned, or if @@ -27,4 +39,5 @@ _Noreturn void abort(void) a_crash(); raise(SIGKILL); _Exit(127); +#endif } diff --git a/system/lib/libc/musl/src/exit/atexit.c b/system/lib/libc/musl/src/exit/atexit.c index 92c91c9de8c9b..4d9571dd80137 100644 --- a/system/lib/libc/musl/src/exit/atexit.c +++ b/system/lib/libc/musl/src/exit/atexit.c @@ -41,11 +41,11 @@ void __funcs_on_exit() UNLOCK(lock); } -void __cxa_finalize(void *dso) +void ___cxa_finalize(void *dso) { } -int __cxa_atexit(void (*func)(void *), void *arg, void *dso) +int ___cxa_atexit(void (*func)(void *), void *arg, void *dso) { LOCK(lock); @@ -85,7 +85,13 @@ static void call(void *p) ((void (*)(void))(uintptr_t)p)(); } -int atexit(void (*func)(void)) +int __atexit(void (*func)(void)) { - return __cxa_atexit(call, (void *)(uintptr_t)func, 0); + return ___cxa_atexit(call, (void *)(uintptr_t)func, 0); } + +// XXX: EMSCRIPTEN: Use weak aliases here so that we can override these symbols +// in when EXIT_RUNTIME is set to 0. +weak_alias(__atexit, atexit); +weak_alias(___cxa_atexit, __cxa_atexit); +weak_alias(___cxa_finalize, __cxa_finalize); diff --git a/system/lib/libc/musl/src/fcntl/fcntl.c b/system/lib/libc/musl/src/fcntl/fcntl.c index d3bff5c486808..dbc913ba703a5 100644 --- a/system/lib/libc/musl/src/fcntl/fcntl.c +++ b/system/lib/libc/musl/src/fcntl/fcntl.c @@ -3,37 +3,65 @@ #include #include #include "syscall.h" +#include int fcntl(int fd, int cmd, ...) { +#ifdef __EMSCRIPTEN__ + // XXX Emscripten: According to the va_arg man page it is undefined behaviour to + // read arguments that are not passed. This can lead to a false positive + // in SAFE_HEAP, so avoid it. + unsigned long arg = 0; + if (cmd != F_GETFL && cmd != F_GETFD && cmd != F_GETOWN) { + va_list ap; + va_start(ap, cmd); + arg = va_arg(ap, unsigned long); + va_end(ap); + } +#else unsigned long arg; va_list ap; va_start(ap, cmd); arg = va_arg(ap, unsigned long); va_end(ap); +#endif if (cmd == F_SETFL) arg |= O_LARGEFILE; if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg); if (cmd == F_GETOWN) { struct f_owner_ex ex; int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex); +#ifdef __EMSCRIPTEN__ + // XXX Emscripten: Mirror the behaviour/limitation of glibc which + // will misinterpret negative PIDs in range of -1 to -4095 as being + // errno values. + if (ret == -EINVAL) ret = __syscall(SYS_fcntl, fd, cmd, (void *)arg); +#else if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg); +#endif if (ret) return __syscall_ret(ret); return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; } if (cmd == F_DUPFD_CLOEXEC) { int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg); if (ret != -EINVAL) { - if (ret >= 0) - __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process + if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); +#endif return __syscall_ret(ret); } ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0); if (ret != -EINVAL) { +#ifdef __EMSCRIPTEN__ + if (ret >= 0) __wasi_fd_close(ret); +#else if (ret >= 0) __syscall(SYS_close, ret); +#endif return __syscall_ret(-EINVAL); } ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg); +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC); +#endif return __syscall_ret(ret); } switch (cmd) { diff --git a/system/lib/libc/musl/src/fcntl/open.c b/system/lib/libc/musl/src/fcntl/open.c index 4c3c82759c1b2..b95a90e017274 100644 --- a/system/lib/libc/musl/src/fcntl/open.c +++ b/system/lib/libc/musl/src/fcntl/open.c @@ -14,8 +14,10 @@ int open(const char *filename, int flags, ...) } int fd = __sys_open_cp(filename, flags, mode); +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (fd>=0 && (flags & O_CLOEXEC)) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); +#endif return __syscall_ret(fd); } diff --git a/system/lib/libc/musl/src/internal/dynlink.h b/system/lib/libc/musl/src/internal/dynlink.h index 40c743e2fcbe0..55482cf5f7959 100644 --- a/system/lib/libc/musl/src/internal/dynlink.h +++ b/system/lib/libc/musl/src/internal/dynlink.h @@ -7,6 +7,40 @@ #include #include +#ifdef __EMSCRIPTEN__ +// Declare `struct dso` in this header so that it is visible to gen_struct_info. + +#include + +struct dso { + // Pointer back to the dlevent in the event sequence which loaded this DSO. + struct dlevent* event; + + // Flags used to open the library. We need to cache these so that other + // threads can mirror the open library state. + int flags; + + // Location in memory/table of static data/static function addresses + // The first thread to load a given module alloces the memory and table + // address space and then sets this field to non-zero. + uint8_t mem_allocated; + void* mem_addr; + size_t mem_size; + void* table_addr; + size_t table_size; + + // For DSO load events, where the DSO comes from a file on disc, this + // is a pointer the file data read in by the laoding thread and shared with + // others. + uint8_t* file_data; + size_t file_data_size; + + // Flexible array; must be final element of struct + char name[]; +}; + +#else + #if UINTPTR_MAX == 0xffffffff typedef Elf32_Ehdr Ehdr; typedef Elf32_Phdr Phdr; @@ -105,6 +139,8 @@ struct fdpic_dummy_loadmap { typedef void (*stage2_func)(unsigned char *, size_t *); +#endif // __EMSCRIPTEN__ + hidden void *__dlsym(void *restrict, const char *restrict, void *restrict); hidden void __dl_seterr(const char *, ...); diff --git a/system/lib/libc/musl/src/internal/libc.c b/system/lib/libc/musl/src/internal/libc.c index cb05181084a57..c84ed3d2524c1 100644 --- a/system/lib/libc/musl/src/internal/libc.c +++ b/system/lib/libc/musl/src/internal/libc.c @@ -3,7 +3,9 @@ struct __libc __libc; size_t __hwcap; +#ifndef __EMSCRIPTEN__ char *__progname=0, *__progname_full=0; weak_alias(__progname, program_invocation_short_name); weak_alias(__progname_full, program_invocation_name); +#endif diff --git a/system/lib/libc/musl/src/internal/libc.h b/system/lib/libc/musl/src/internal/libc.h index 619bba8613e8d..b0b3f20cf6a4c 100644 --- a/system/lib/libc/musl/src/internal/libc.h +++ b/system/lib/libc/musl/src/internal/libc.h @@ -4,6 +4,7 @@ #include #include #include +#include struct __locale_map; @@ -53,6 +54,11 @@ extern char *__progname, *__progname_full; extern hidden const char __libc_version[]; hidden void __synccall(void (*)(void *), void *); +#ifdef __EMSCRIPTEN__ +hidden int __setxid_emscripten(); +#define __setxid(a, b, c, d) __setxid_emscripten() +#else hidden int __setxid(int, int, int, int); +#endif #endif diff --git a/system/lib/libc/musl/src/internal/libm.h b/system/lib/libc/musl/src/internal/libm.h index 72ad17d8ebe80..a47208aa6ad3c 100644 --- a/system/lib/libc/musl/src/internal/libm.h +++ b/system/lib/libc/musl/src/internal/libm.h @@ -177,6 +177,13 @@ static inline void fp_force_evall(long double x) } #endif +#ifdef __EMSCRIPTEN__ +/* + * asm.js doesn't have user-accessible floating point exceptions, so there's + * no point in trying to force expression evaluations to produce them. + */ +#define FORCE_EVAL(x) +#else #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ fp_force_evalf(x); \ @@ -186,6 +193,7 @@ static inline void fp_force_evall(long double x) fp_force_evall(x); \ } \ } while(0) +#endif #define asuint(f) ((union{float _f; uint32_t _i;}){f})._i #define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f diff --git a/system/lib/libc/musl/src/internal/locale_impl.h b/system/lib/libc/musl/src/internal/locale_impl.h index 4431a92eb7112..9a7b07c4aac0e 100644 --- a/system/lib/libc/musl/src/internal/locale_impl.h +++ b/system/lib/libc/musl/src/internal/locale_impl.h @@ -31,15 +31,31 @@ hidden char *__gettextdomain(void); #define LOC_MAP_FAILED ((const struct __locale_map *)-1) +#if __EMSCRIPTEN__ +// Disable message translation completely under emscripten since we don't +// support loading any actual locale data, and even looking up the current +// local via CURRENT_LOCALE via TLS is not free. +#define LCTRANS(msg, lc, loc) msg +#define LCTRANS_CUR(msg) msg +#else #define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)]) #define LCTRANS_CUR(msg) __lctrans_cur(msg) +#endif #define C_LOCALE ((locale_t)&__c_locale) #define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale) +#ifdef __EMSCRIPTEN__ +extern _Thread_local locale_t __tls_locale; + +#define CURRENT_LOCALE (__tls_locale) + +#define CURRENT_UTF8 (!!__tls_locale->cat[LC_CTYPE]) +#else #define CURRENT_LOCALE (__pthread_self()->locale) #define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE]) +#endif #undef MB_CUR_MAX #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1) diff --git a/system/lib/libc/musl/src/internal/progname.c b/system/lib/libc/musl/src/internal/progname.c new file mode 100644 index 0000000000000..ffefb792e6989 --- /dev/null +++ b/system/lib/libc/musl/src/internal/progname.c @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ + +#ifdef __EMSCRIPTEN__ +#include +#include + +#include "emscripten_internal.h" + +char *__progname=0, *__progname_full=0; + +weak_alias(__progname, program_invocation_short_name); +weak_alias(__progname_full, program_invocation_name); + +__attribute__((constructor)) +static void __progname_ctor(void) +{ + static char full_path[PATH_MAX]; + char *basename; + + _emscripten_get_progname(full_path, sizeof(full_path)); + + basename = strrchr(full_path, '/'); + if (basename == NULL) { + basename = full_path; + } else { + basename++; + } + + __progname_full = full_path; + __progname = basename; +} +#endif diff --git a/system/lib/libc/musl/src/internal/proxying_notification_state.h b/system/lib/libc/musl/src/internal/proxying_notification_state.h new file mode 100644 index 0000000000000..37a648315c003 --- /dev/null +++ b/system/lib/libc/musl/src/internal/proxying_notification_state.h @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ + +#pragma once + +// Flag values used when creating postMessage notifications and when freeing +// proxying queues. New postMessages are created for new work unless the +// relevant task queue is in state NOTIFICATION_PENDING and proxying queues can +// only be freed when all of their task queues are in NOTIFICATION_NONE state. +typedef enum notification_state { + NOTIFICATION_NONE = 0, + NOTIFICATION_RECEIVED = 1, + NOTIFICATION_PENDING = 2, +} notification_state; diff --git a/system/lib/libc/musl/src/internal/pthread_impl.h b/system/lib/libc/musl/src/internal/pthread_impl.h index de2b9d8b477e6..a366b6cef8eb3 100644 --- a/system/lib/libc/musl/src/internal/pthread_impl.h +++ b/system/lib/libc/musl/src/internal/pthread_impl.h @@ -9,6 +9,12 @@ #include "libc.h" #include "syscall.h" #include "atomic.h" +#ifdef __EMSCRIPTEN__ +#include "em_task_queue.h" +#include "thread_mailbox.h" +#include "threading_internal.h" +#include +#endif #include "futex.h" #include "pthread_arch.h" @@ -33,7 +39,10 @@ struct pthread { /* Part 2 -- implementation details, non-ABI. */ int tid; +#ifndef __EMSCRIPTEN__ + // Emscripten uses C11 _Thread_local instead for errno int errno_val; +#endif volatile int detach_state; volatile int cancel; volatile unsigned char canceldisable, cancelasync; @@ -54,7 +63,10 @@ struct pthread { } robust_list; int h_errno_val; volatile int timer_id; +#ifndef __EMSCRIPTEN__ + // Emscripten uses C11 _Thread_local instead for locale locale_t locale; +#endif volatile int killlock[1]; char *dlerror_buf; void *stdio_locks; @@ -65,10 +77,59 @@ struct pthread { uintptr_t canary; uintptr_t *dtv; #endif + +// XXX Emscripten: Need some custom thread control structures. +#ifdef __EMSCRIPTEN__ + // If --threadprofiler is enabled, this pointer is allocated to contain + // internal information about the thread state for profiling purposes. + thread_profiler_block * _Atomic profilerBlock; + // The TLS base to use the main module TLS data. Secondary modules + // still require dynamic allocation. + void* tls_base; + // The lowest level of the proxying system. Other threads can enqueue + // messages on the mailbox and notify this thread to asynchronously + // process them once it returns to its event loop. When this thread is + // shut down, the mailbox is closed (see below) to prevent further + // messages from being enqueued and all the remaining queued messages + // are dequeued and their shutdown handlers are executed. This allows + // other threads waiting for their messages to be processed to be + // notified that their messages will not be processed after all. + em_task_queue* mailbox; + // To ensure that no other thread is concurrently enqueueing a message + // when this thread shuts down, maintain an atomic refcount. Enqueueing + // threads atomically increment the count from a nonzero number to + // acquire the mailbox and decrement the count when they finish. When + // this thread shuts down it will atomically decrement the count and + // wait until it reaches 0, at which point the mailbox is considered + // closed and no further messages will be enqueued. + _Atomic int mailbox_refcount; + // Whether the thread has executed an `Atomics.waitAsync` on this + // pthread struct and can be notified of new mailbox messages via + // `Atomics.notify`. Otherwise, such as when the environment does not + // implement `Atomics.waitAsync` or when the thread has not had a chance + // to initialize itself yet, the notification has to fall back to the + // postMessage path. Once this becomes true, it remains true so we never + // fall back to postMessage unnecessarily. + _Atomic int waiting_async; + // The address the thread is currently waiting on in emscripten_futex_wait. + // + // This field encodes the state using the following bitmask: + // - NULL: Not waiting, no pending notification. + // - NOTIFY_BIT (0x1): Not waiting, but a notification was sent. + // - addr: Waiting on `addr`, no pending notification. + // - addr | NOTIFY_BIT: Waiting on `addr`, notification sent. + // + // Since futex addresses must be 4-byte aligned, the low bit is safe to use. + _Atomic uintptr_t wait_addr; +#endif }; +#ifdef __EMSCRIPTEN__ +#define NOTIFY_BIT (1 << 0) +#endif + enum { - DT_EXITED = 0, + DT_EXITED, DT_EXITING, DT_JOINABLE, DT_DETACHED, @@ -99,6 +160,12 @@ enum { #define _rw_lock __u.__vi[0] #define _rw_waiters __u.__vi[1] #define _rw_shared __u.__i[2] +#ifdef __EMSCRIPTEN__ +// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, so use an extra field +// _rw_wr_owner to record which thread owns the write lock in order to avoid hangs. +// Points to the pthread that currently has the write lock. +#define _rw_wr_owner __u.__vi[3] +#endif #define _b_lock __u.__vi[0] #define _b_waiters __u.__vi[1] #define _b_limit __u.__i[2] @@ -169,14 +236,22 @@ static inline void __wake(volatile void *addr, int cnt, int priv) { if (priv) priv = FUTEX_PRIVATE; if (cnt<0) cnt = INT_MAX; +#ifdef __EMSCRIPTEN__ + emscripten_futex_wake(addr, (cnt)<0?INT_MAX:(cnt)); +#else __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); +#endif } static inline void __futexwait(volatile void *addr, int val, int priv) { +#ifdef __EMSCRIPTEN__ + __wait(addr, NULL, val, priv); +#else if (priv) priv = FUTEX_PRIVATE; __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); +#endif } hidden void __acquire_ptc(void); @@ -194,7 +269,13 @@ extern hidden volatile int __abort_lock[1]; extern hidden unsigned __default_stacksize; extern hidden unsigned __default_guardsize; + +#ifdef __EMSCRIPTEN__ +// Keep in sync with DEFAULT_PTHREAD_STACK_SIZE in settings.js +#define DEFAULT_STACK_SIZE (64*1024) +#else #define DEFAULT_STACK_SIZE 131072 +#endif #define DEFAULT_GUARD_SIZE 8192 #define DEFAULT_STACK_MAX (8<<20) @@ -202,4 +283,13 @@ extern hidden unsigned __default_guardsize; #define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1) +#ifdef __EMSCRIPTEN_SHARED_MEMORY__ +pid_t gettid(void); +// Unlike `__pthread_self()->tid, `gettid` works under both wasm workers and +// pthreads. +#define CURRENT_THREAD_ID gettid() +#else +#define CURRENT_THREAD_ID __pthread_self()->tid +#endif + #endif diff --git a/system/lib/libc/musl/src/internal/stdio_impl.h b/system/lib/libc/musl/src/internal/stdio_impl.h index 0b2438d613fe9..3dded20e50149 100644 --- a/system/lib/libc/musl/src/internal/stdio_impl.h +++ b/system/lib/libc/musl/src/internal/stdio_impl.h @@ -6,9 +6,15 @@ #define UNGET 8 +#if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_SHARED_MEMORY__) +#define FFINALLOCK(f) +#define FLOCK(f) +#define FUNLOCK(f) +#else #define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0) #define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0) #define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0) +#endif #define F_PERM 1 #define F_NORD 4 @@ -66,7 +72,7 @@ hidden int __towrite(FILE *); hidden void __stdio_exit(void); hidden void __stdio_exit_needed(void); -#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303) +#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303) && !defined(__EMSCRIPTEN__) __attribute__((visibility("protected"))) #endif int __overflow(FILE *, int), __uflow(FILE *); @@ -109,4 +115,12 @@ hidden void __getopt_msg(const char *, const char *, const char *, size_t); hidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t); hidden int __fclose_ca(FILE *); +// XXX EMSCRIPTEN +extern int vfiprintf(FILE *restrict f, const char *restrict fmt, va_list ap); +extern int vsiprintf(char *restrict s, const char *restrict fmt, va_list ap); +extern int vsniprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); +extern int __small_vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap); +extern int __small_vsprintf(char *restrict s, const char *restrict fmt, va_list ap); +extern int __small_vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap); + #endif diff --git a/system/lib/libc/musl/src/internal/syscall.h b/system/lib/libc/musl/src/internal/syscall.h index 2d8a5c134db0f..4476dbe7db09a 100644 --- a/system/lib/libc/musl/src/internal/syscall.h +++ b/system/lib/libc/musl/src/internal/syscall.h @@ -19,21 +19,44 @@ #endif #ifndef __scc +#ifdef __EMSCRIPTEN__ +// With emscripten we allow the passing of longer-than-word-sized +// argument (such as off_t on wasm32) and let binaryen handle splitting +// them into a pair of i32 arguments. +#define __scc(X) ((long long) (X)) +#else #define __scc(X) ((long) (X)) +#endif typedef long syscall_arg_t; #endif +#ifdef __cplusplus +extern "C" { +#endif hidden long __syscall_ret(unsigned long), __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t); +#ifdef __cplusplus +} +#endif +#ifndef __EMSCRIPTEN__ #define __syscall1(n,a) __syscall1(n,__scc(a)) #define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) #define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) #define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) #define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) #define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#define __syscall7(n,a,b,c,d,e,f,g) __syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g)) +#else // __EMSCRIPTEN__ +#define __syscall_emscripten(n, ...) n(__VA_ARGS__) +#define __syscall_emscripten0(n) __syscall_emscripten(n) +#define __syscall_emscripten1(n,a) __syscall_emscripten(n,__scc(a)) +#define __syscall_emscripten2(n,a,b) __syscall_emscripten(n,__scc(a),__scc(b)) +#define __syscall_emscripten3(n,a,b,c) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c)) +#define __syscall_emscripten4(n,a,b,c,d) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d)) +#define __syscall_emscripten5(n,a,b,c,d,e) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) +#define __syscall_emscripten6(n,a,b,c,d,e,f) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) +#endif // __EMSCRIPTEN__ #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,) @@ -41,12 +64,18 @@ hidden long __syscall_ret(unsigned long), #define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b) #define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) +#ifndef __EMSCRIPTEN__ #define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) +#else +#define __syscall(...) __SYSCALL_DISP(__syscall_emscripten,__VA_ARGS__) +#endif + #define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) #define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f)) #define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f)) +#ifndef __EMSCRIPTEN__ #define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0) #define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0) #define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0) @@ -56,9 +85,16 @@ hidden long __syscall_ret(unsigned long), #define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) +#else // __EMSCRIPTEN__ +#define __syscall_cp(...) __syscall(__VA_ARGS__) +#endif // __EMSCRIPTEN__ + #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) -static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f) +#ifdef __EMSCRIPTEN__ +#define __socketcall(nm,a,b,c,d,e,f) __syscall(SYS_##nm, a, b, c, d, e, f) +#define __socketcall_cp(nm,a,b,c,d,e,f) __syscall_cp(SYS_##nm, a, b, c, d, e, f) +#else { long r; if (cp) r = __syscall_cp(sys, a, b, c, d, e, f); @@ -74,6 +110,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) #define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \ __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) +#endif /* fixup legacy 16-bit junk */ @@ -97,7 +134,6 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #undef SYS_setgid #undef SYS_setfsuid #undef SYS_setfsgid -#define SYS_lchown SYS_lchown32 #define SYS_getuid SYS_getuid32 #define SYS_getgid SYS_getgid32 #define SYS_geteuid SYS_geteuid32 @@ -111,7 +147,6 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #define SYS_getresuid SYS_getresuid32 #define SYS_setresgid SYS_setresgid32 #define SYS_getresgid SYS_getresgid32 -#define SYS_chown SYS_chown32 #define SYS_setuid SYS_setuid32 #define SYS_setgid SYS_setgid32 #define SYS_setfsuid SYS_setfsuid32 @@ -373,6 +408,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #define SIOCGSTAMPNS_OLD 0x8907 #endif +#ifndef __EMSCRIPTEN__ #ifdef SYS_open #define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) #define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) @@ -384,6 +420,12 @@ static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, #define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) #define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) #endif +#else // __EMSCRIPTEN__ +#define __sys_open2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) +#define __sys_open3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) +#define __sys_open_cp2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) +#endif #define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__) #define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__)) @@ -414,7 +456,11 @@ hidden long __emulate_wait4(int, int *, int, void *, int); #define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d)) #define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d)) +#ifdef __cplusplus +hidden void __procfdname(char __buf[], unsigned); +#else hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); +#endif hidden void *__vdsosym(const char *, const char *); diff --git a/system/lib/libc/musl/src/linux/gettid.c b/system/lib/libc/musl/src/linux/gettid.c index 70767137e92fe..cd401dd52a3cd 100644 --- a/system/lib/libc/musl/src/linux/gettid.c +++ b/system/lib/libc/musl/src/linux/gettid.c @@ -2,7 +2,35 @@ #include #include "pthread_impl.h" +#ifdef __EMSCRIPTEN__ +weak int emscripten_wasm_worker_self_id(); +#endif + +#if defined(__EMSCRIPTEN_WASM_WORKERS__) && defined(__EMSCRIPTEN_PTHREADS__) +#error "this file should be compiled with either wasm workers or pthreads but not both" +#endif + pid_t gettid(void) { +#ifdef __EMSCRIPTEN_WASM_WORKERS__ + // Offset the worker ID by 1 so we never return 0 from this function. + // Strangly we cannot assume the existence of emscripten_wasm_worker_self_id + // here because libc-ww is also used for `-sSHARED_MEMORY` builds (without + // libwasm_workers linked in. + if (emscripten_wasm_worker_self_id) { + return emscripten_wasm_worker_self_id() + 1; + } else { + return 42; + } +#else +#if defined(__EMSCRIPTEN_PTHREADS__) + // The pthread-variant of libc can also be used alongside wasm workers. + // We detect that via a weak reference to the self_id function. + if (emscripten_wasm_worker_self_id) { + pid_t rtn = emscripten_wasm_worker_self_id(); + if (rtn) return rtn; + } +#endif return __pthread_self()->tid; +#endif } diff --git a/system/lib/libc/musl/src/linux/sbrk.c b/system/lib/libc/musl/src/linux/sbrk.c index bb86630584441..8e3a9b6645d68 100644 --- a/system/lib/libc/musl/src/linux/sbrk.c +++ b/system/lib/libc/musl/src/linux/sbrk.c @@ -1,3 +1,4 @@ +#if !__EMSCRIPTEN__ /* Emscripten controls sbrk itself */ #define _BSD_SOURCE #include #include @@ -9,3 +10,5 @@ void *sbrk(intptr_t inc) if (inc) return (void *)__syscall_ret(-ENOMEM); return (void *)__syscall(SYS_brk, 0); } +#endif + diff --git a/system/lib/libc/musl/src/linux/statx.c b/system/lib/libc/musl/src/linux/statx.c index 4fb96e4bd1ffd..95307eaaa4ee3 100644 --- a/system/lib/libc/musl/src/linux/statx.c +++ b/system/lib/libc/musl/src/linux/statx.c @@ -7,6 +7,9 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx) { +#ifdef __EMSCRIPTEN__ + int ret; +#else int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx); #ifndef SYS_fstatat @@ -14,6 +17,7 @@ int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct #endif if (ret != -ENOSYS) return __syscall_ret(ret); +#endif struct stat st; ret = fstatat(dirfd, path, &st, flags); diff --git a/system/lib/libc/musl/src/locale/catclose.c b/system/lib/libc/musl/src/locale/catclose.c index 54e24dd2163bc..6f4f77037d2f1 100644 --- a/system/lib/libc/musl/src/locale/catclose.c +++ b/system/lib/libc/musl/src/locale/catclose.c @@ -8,7 +8,9 @@ int catclose (nl_catd catd) { +#ifndef __EMSCRIPTEN__ char *map = (char *)catd; munmap(map, V(map+8)+20); +#endif return 0; } diff --git a/system/lib/libc/musl/src/locale/catgets.c b/system/lib/libc/musl/src/locale/catgets.c index 71c31c1d6d010..b7caaf01e3c7b 100644 --- a/system/lib/libc/musl/src/locale/catgets.c +++ b/system/lib/libc/musl/src/locale/catgets.c @@ -5,6 +5,7 @@ #include #include +#ifndef __EMSCRIPTEN__ #define V(p) be32toh(*(uint32_t *)(p)) static int cmp(const void *a, const void *b) @@ -12,9 +13,13 @@ static int cmp(const void *a, const void *b) uint32_t x = V(a), y = V(b); return xy ? 1 : 0; } +#endif char *catgets (nl_catd catd, int set_id, int msg_id, const char *s) { +#ifdef __EMSCRIPTEN__ + return (char *)s; +#else const char *map = (const char *)catd; uint32_t nsets = V(map+4); const char *sets = map+20; @@ -35,4 +40,5 @@ char *catgets (nl_catd catd, int set_id, int msg_id, const char *s) return (char *)s; } return (char *)(strings + V(msg+8)); +#endif } diff --git a/system/lib/libc/musl/src/locale/catopen.c b/system/lib/libc/musl/src/locale/catopen.c index 97f2446d37f98..5bf2e9031dadf 100644 --- a/system/lib/libc/musl/src/locale/catopen.c +++ b/system/lib/libc/musl/src/locale/catopen.c @@ -9,6 +9,7 @@ #include #include "libc.h" +#ifndef __EMSCRIPTEN__ #define V(p) be32toh(*(uint32_t *)(p)) static nl_catd do_catopen(const char *name) @@ -24,9 +25,11 @@ static nl_catd do_catopen(const char *name) } return (nl_catd)map; } +#endif nl_catd catopen(const char *name, int oflag) { +#ifndef __EMSCRIPTEN__ nl_catd catd; if (strchr(name, '/')) return do_catopen(name); @@ -75,5 +78,6 @@ nl_catd catopen(const char *name, int oflag) if (catd != (nl_catd)-1) return catd; } errno = ENOENT; +#endif return (nl_catd)-1; } diff --git a/system/lib/libc/musl/src/locale/dcngettext.c b/system/lib/libc/musl/src/locale/dcngettext.c index 0b53286db7536..56bee9931d146 100644 --- a/system/lib/libc/musl/src/locale/dcngettext.c +++ b/system/lib/libc/musl/src/locale/dcngettext.c @@ -189,7 +189,7 @@ char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, snprintf(name, sizeof name, "%s/%.*s%.*s/%s/%s.mo\0", dirname, (int)loclen, locname, (int)alt_modlen, modname, catname, domainname); - if (map = __map_file(name, &map_size)) break; + if ((map = __map_file(name, &map_size))) break; /* Try dropping @mod, _YY, then both. */ if (alt_modlen) { diff --git a/system/lib/libc/musl/src/locale/locale_map.c b/system/lib/libc/musl/src/locale/locale_map.c index da61f7fc032c5..d696066cd3287 100644 --- a/system/lib/libc/musl/src/locale/locale_map.c +++ b/system/lib/libc/musl/src/locale/locale_map.c @@ -12,12 +12,14 @@ #define realloc undef #define free undef +#ifndef __EMSCRIPTEN__ const char *__lctrans_impl(const char *msg, const struct __locale_map *lm) { const char *trans = 0; if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg); return trans ? trans : msg; } +#endif static const char envvars[][12] = { "LC_CTYPE", @@ -63,6 +65,7 @@ const struct __locale_map *__get_locale(int cat, const char *val) for (p=loc_head; p; p=p->next) if (!strcmp(val, p->name)) return p; +#ifndef __EMSCRIPTEN__ // don't support MUSL_LOCPATH which uses mmap if (!libc.secure) path = getenv("MUSL_LOCPATH"); /* FIXME: add a default path? */ @@ -91,6 +94,7 @@ const struct __locale_map *__get_locale(int cat, const char *val) break; } } +#endif /* If no locale definition was found, make a locale map * object anyway to store the name, which is kept for the diff --git a/system/lib/libc/musl/src/locale/uselocale.c b/system/lib/libc/musl/src/locale/uselocale.c index 0fc5ecbc07f29..c7b68b5a0d14e 100644 --- a/system/lib/libc/musl/src/locale/uselocale.c +++ b/system/lib/libc/musl/src/locale/uselocale.c @@ -2,13 +2,24 @@ #include "pthread_impl.h" #include "libc.h" +#ifdef __EMSCRIPTEN__ +_Thread_local locale_t __tls_locale = &libc.global_locale; +#endif + locale_t __uselocale(locale_t new) { +#ifdef __EMSCRIPTEN__ + locale_t old = __tls_locale; + locale_t global = &libc.global_locale; + + if (new) __tls_locale = new == LC_GLOBAL_LOCALE ? global : new; +#else pthread_t self = __pthread_self(); locale_t old = self->locale; locale_t global = &libc.global_locale; if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new; +#endif return old == global ? LC_GLOBAL_LOCALE : old; } diff --git a/system/lib/libc/musl/src/malloc/reallocarray.c b/system/lib/libc/musl/src/malloc/reallocarray.c new file mode 100644 index 0000000000000..bcf5f4346d0fb --- /dev/null +++ b/system/lib/libc/musl/src/malloc/reallocarray.c @@ -0,0 +1,17 @@ +#define _BSD_SOURCE +#include +#include + +#ifdef __EMSCRIPTEN__ +/* Must be weak so that lsan can override */ +weak +#endif +void *reallocarray(void *ptr, size_t m, size_t n) +{ + if (n && m > -1 / n) { + errno = ENOMEM; + return 0; + } + + return realloc(ptr, m * n); +} diff --git a/system/lib/libc/musl/src/math/ceil.c b/system/lib/libc/musl/src/math/ceil.c index b13e6f2d63689..93265657d3585 100644 --- a/system/lib/libc/musl/src/math/ceil.c +++ b/system/lib/libc/musl/src/math/ceil.c @@ -1,14 +1,21 @@ #include "libm.h" +#ifndef __wasm__ #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON #endif static const double_t toint = 1/EPS; +#endif double ceil(double x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_ceil(x); +#else union {double f; uint64_t i;} u = {x}; int e = u.i >> 52 & 0x7ff; double_t y; @@ -28,4 +35,5 @@ double ceil(double x) if (y < 0) return x + y + 1; return x + y; +#endif } diff --git a/system/lib/libc/musl/src/math/ceilf.c b/system/lib/libc/musl/src/math/ceilf.c index 869835f397838..9a071337029a7 100644 --- a/system/lib/libc/musl/src/math/ceilf.c +++ b/system/lib/libc/musl/src/math/ceilf.c @@ -2,6 +2,11 @@ float ceilf(float x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_ceilf(x); +#else union {float f; uint32_t i;} u = {x}; int e = (int)(u.i >> 23 & 0xff) - 0x7f; uint32_t m; @@ -24,4 +29,5 @@ float ceilf(float x) u.f = 1.0; } return u.f; +#endif } diff --git a/system/lib/libc/musl/src/math/copysign.c b/system/lib/libc/musl/src/math/copysign.c index b09331b6876e7..1fc78c9f23ad1 100644 --- a/system/lib/libc/musl/src/math/copysign.c +++ b/system/lib/libc/musl/src/math/copysign.c @@ -1,8 +1,14 @@ #include "libm.h" double copysign(double x, double y) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_copysign(x, y); +#else union {double f; uint64_t i;} ux={x}, uy={y}; ux.i &= -1ULL/2; ux.i |= uy.i & 1ULL<<63; return ux.f; +#endif } diff --git a/system/lib/libc/musl/src/math/copysignf.c b/system/lib/libc/musl/src/math/copysignf.c index 0af6ae9b2155d..76d2d255dcf82 100644 --- a/system/lib/libc/musl/src/math/copysignf.c +++ b/system/lib/libc/musl/src/math/copysignf.c @@ -3,8 +3,14 @@ float copysignf(float x, float y) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_copysignf(x, y); +#else union {float f; uint32_t i;} ux={x}, uy={y}; ux.i &= 0x7fffffff; ux.i |= uy.i & 0x80000000; return ux.f; +#endif } diff --git a/system/lib/libc/musl/src/math/fabs.c b/system/lib/libc/musl/src/math/fabs.c index e8258cfdbcf1a..566a461ffdd37 100644 --- a/system/lib/libc/musl/src/math/fabs.c +++ b/system/lib/libc/musl/src/math/fabs.c @@ -3,7 +3,13 @@ double fabs(double x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_fabs(x); +#else union {double f; uint64_t i;} u = {x}; u.i &= -1ULL/2; return u.f; +#endif } diff --git a/system/lib/libc/musl/src/math/fabsf.c b/system/lib/libc/musl/src/math/fabsf.c index 4efc8d686dcc4..1ff074a720c75 100644 --- a/system/lib/libc/musl/src/math/fabsf.c +++ b/system/lib/libc/musl/src/math/fabsf.c @@ -3,7 +3,13 @@ float fabsf(float x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_fabsf(x); +#else union {float f; uint32_t i;} u = {x}; u.i &= 0x7fffffff; return u.f; +#endif } diff --git a/system/lib/libc/musl/src/math/floor.c b/system/lib/libc/musl/src/math/floor.c index 14a31cd8c4c54..179a9aca1de50 100644 --- a/system/lib/libc/musl/src/math/floor.c +++ b/system/lib/libc/musl/src/math/floor.c @@ -1,14 +1,21 @@ #include "libm.h" +#ifndef __wasm__ #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON #endif static const double_t toint = 1/EPS; +#endif double floor(double x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_floor(x); +#else union {double f; uint64_t i;} u = {x}; int e = u.i >> 52 & 0x7ff; double_t y; @@ -28,4 +35,5 @@ double floor(double x) if (y > 0) return x + y - 1; return x + y; +#endif } diff --git a/system/lib/libc/musl/src/math/floorf.c b/system/lib/libc/musl/src/math/floorf.c index dceec739dbef5..4552d38bc5723 100644 --- a/system/lib/libc/musl/src/math/floorf.c +++ b/system/lib/libc/musl/src/math/floorf.c @@ -2,6 +2,11 @@ float floorf(float x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_floorf(x); +#else union {float f; uint32_t i;} u = {x}; int e = (int)(u.i >> 23 & 0xff) - 0x7f; uint32_t m; @@ -24,4 +29,5 @@ float floorf(float x) u.f = -1.0; } return u.f; +#endif } diff --git a/system/lib/libc/musl/src/math/fma.c b/system/lib/libc/musl/src/math/fma.c index adfadca8c256f..6b1a6d02a01c5 100644 --- a/system/lib/libc/musl/src/math/fma.c +++ b/system/lib/libc/musl/src/math/fma.c @@ -41,7 +41,9 @@ static void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y) double fma(double x, double y, double z) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif /* normalize so top 10bits and last bit are 0 */ struct num nx, ny, nz; diff --git a/system/lib/libc/musl/src/math/fmaf.c b/system/lib/libc/musl/src/math/fmaf.c index 7c65acf1fc5e0..bb4f6f1daa6eb 100644 --- a/system/lib/libc/musl/src/math/fmaf.c +++ b/system/lib/libc/musl/src/math/fmaf.c @@ -38,7 +38,9 @@ */ float fmaf(float x, float y, float z) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif double xy, result; union {double f; uint64_t i;} u; int e; diff --git a/system/lib/libc/musl/src/math/fmal.c b/system/lib/libc/musl/src/math/fmal.c index 4506aac6f6abb..ac8ecbbb2a6e0 100644 --- a/system/lib/libc/musl/src/math/fmal.c +++ b/system/lib/libc/musl/src/math/fmal.c @@ -164,7 +164,9 @@ static inline struct dd dd_mul(long double a, long double b) */ long double fmal(long double x, long double y, long double z) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif long double xs, ys, zs, adj; struct dd xy, r; int oround; diff --git a/system/lib/libc/musl/src/math/fmax.c b/system/lib/libc/musl/src/math/fmax.c index 94f0caa17751b..2018a78c6978a 100644 --- a/system/lib/libc/musl/src/math/fmax.c +++ b/system/lib/libc/musl/src/math/fmax.c @@ -6,8 +6,13 @@ double fmax(double x, double y) return y; if (isnan(y)) return x; +// XXX EMSCRIPTEN: use wasm builtins for code size +#ifdef __wasm__ + return __builtin_wasm_max_f64(x, y); +#else /* handle signed zeros, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? y : x; return x < y ? y : x; +#endif } diff --git a/system/lib/libc/musl/src/math/fmaxf.c b/system/lib/libc/musl/src/math/fmaxf.c index 695d8179c6c1c..8524cee49dce3 100644 --- a/system/lib/libc/musl/src/math/fmaxf.c +++ b/system/lib/libc/musl/src/math/fmaxf.c @@ -6,8 +6,13 @@ float fmaxf(float x, float y) return y; if (isnan(y)) return x; +// XXX EMSCRIPTEN: use wasm builtins for code size +#ifdef __wasm__ + return __builtin_wasm_max_f32(x, y); +#else /* handle signed zeroes, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? y : x; return x < y ? y : x; +#endif } diff --git a/system/lib/libc/musl/src/math/fmin.c b/system/lib/libc/musl/src/math/fmin.c index 08a8fd17f29e3..2334d7b898a30 100644 --- a/system/lib/libc/musl/src/math/fmin.c +++ b/system/lib/libc/musl/src/math/fmin.c @@ -6,8 +6,13 @@ double fmin(double x, double y) return y; if (isnan(y)) return x; +// XXX EMSCRIPTEN: use wasm builtins for code size +#ifdef __wasm__ + return __builtin_wasm_min_f64(x, y); +#else /* handle signed zeros, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? x : y; return x < y ? x : y; +#endif } diff --git a/system/lib/libc/musl/src/math/fminf.c b/system/lib/libc/musl/src/math/fminf.c index 3573c7de741e1..bfbaafcef80b9 100644 --- a/system/lib/libc/musl/src/math/fminf.c +++ b/system/lib/libc/musl/src/math/fminf.c @@ -6,8 +6,13 @@ float fminf(float x, float y) return y; if (isnan(y)) return x; +// XXX EMSCRIPTEN: use wasm builtins for code size +#ifdef __wasm__ + return __builtin_wasm_min_f32(x, y); +#else /* handle signed zeros, see C99 Annex F.9.9.2 */ if (signbit(x) != signbit(y)) return signbit(x) ? x : y; return x < y ? x : y; +#endif } diff --git a/system/lib/libc/musl/src/math/ilogb.c b/system/lib/libc/musl/src/math/ilogb.c index 64d40154d60ab..a52d78ef7dcec 100644 --- a/system/lib/libc/musl/src/math/ilogb.c +++ b/system/lib/libc/musl/src/math/ilogb.c @@ -3,7 +3,9 @@ int ilogb(double x) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif union {double f; uint64_t i;} u = {x}; uint64_t i = u.i; int e = i>>52 & 0x7ff; diff --git a/system/lib/libc/musl/src/math/ilogbf.c b/system/lib/libc/musl/src/math/ilogbf.c index e23ba209ec4cd..18aef0ae043dd 100644 --- a/system/lib/libc/musl/src/math/ilogbf.c +++ b/system/lib/libc/musl/src/math/ilogbf.c @@ -3,7 +3,9 @@ int ilogbf(float x) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif union {float f; uint32_t i;} u = {x}; uint32_t i = u.i; int e = i>>23 & 0xff; diff --git a/system/lib/libc/musl/src/math/ilogbl.c b/system/lib/libc/musl/src/math/ilogbl.c index 7b1a9cf8d007f..9931cac52ca6a 100644 --- a/system/lib/libc/musl/src/math/ilogbl.c +++ b/system/lib/libc/musl/src/math/ilogbl.c @@ -9,7 +9,9 @@ int ilogbl(long double x) #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 int ilogbl(long double x) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif union ldshape u = {x}; uint64_t m = u.i.m; int e = u.i.se & 0x7fff; @@ -32,7 +34,9 @@ int ilogbl(long double x) #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 int ilogbl(long double x) { +#ifndef __EMSCRIPTEN__ #pragma STDC FENV_ACCESS ON +#endif union ldshape u = {x}; int e = u.i.se & 0x7fff; diff --git a/system/lib/libc/musl/src/math/log2_small.c b/system/lib/libc/musl/src/math/log2_small.c new file mode 100644 index 0000000000000..0aafad4b86c1c --- /dev/null +++ b/system/lib/libc/musl/src/math/log2_small.c @@ -0,0 +1,122 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_log2.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* + * Return the base 2 logarithm of x. See log.c for most comments. + * + * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2 + * as in log.c, then combine and scale in extra precision: + * log2(x) = (f - f*f/2 + r)/log(2) + k + */ + +#include +#include + +static const double +ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ +ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +double log2(double x) +{ + union {double f; uint64_t i;} u = {x}; + double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo; + uint32_t hx; + int k; + + hx = u.i>>32; + k = 0; + if (hx < 0x00100000 || hx>>31) { + if (u.i<<1 == 0) + return -1/(x*x); /* log(+-0)=-inf */ + if (hx>>31) + return (x-x)/0.0; /* log(-#) = NaN */ + /* subnormal number, scale x up */ + k -= 54; + x *= 0x1p54; + u.f = x; + hx = u.i>>32; + } else if (hx >= 0x7ff00000) { + return x; + } else if (hx == 0x3ff00000 && u.i<<32 == 0) + return 0; + + /* reduce x into [sqrt(2)/2, sqrt(2)] */ + hx += 0x3ff00000 - 0x3fe6a09e; + k += (int)(hx>>20) - 0x3ff; + hx = (hx&0x000fffff) + 0x3fe6a09e; + u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); + x = u.f; + + f = x - 1.0; + hfsq = 0.5*f*f; + s = f/(2.0+f); + z = s*s; + w = z*z; + t1 = w*(Lg2+w*(Lg4+w*Lg6)); + t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + R = t2 + t1; + + /* + * f-hfsq must (for args near 1) be evaluated in extra precision + * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2). + * This is fairly efficient since f-hfsq only depends on f, so can + * be evaluated in parallel with R. Not combining hfsq with R also + * keeps R small (though not as small as a true `lo' term would be), + * so that extra precision is not needed for terms involving R. + * + * Compiler bugs involving extra precision used to break Dekker's + * theorem for spitting f-hfsq as hi+lo, unless double_t was used + * or the multi-precision calculations were avoided when double_t + * has extra precision. These problems are now automatically + * avoided as a side effect of the optimization of combining the + * Dekker splitting step with the clear-low-bits step. + * + * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra + * precision to avoid a very large cancellation when x is very near + * these values. Unlike the above cancellations, this problem is + * specific to base 2. It is strange that adding +-1 is so much + * harder than adding +-ln2 or +-log10_2. + * + * This uses Dekker's theorem to normalize y+val_hi, so the + * compiler bugs are back in some configurations, sigh. And I + * don't want to used double_t to avoid them, since that gives a + * pessimization and the support for avoiding the pessimization + * is not yet available. + * + * The multi-precision calculations for the multiplications are + * routine. + */ + + /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ + hi = f - hfsq; + u.f = hi; + u.i &= (uint64_t)-1<<32; + hi = u.f; + lo = f - hi - hfsq + s*(hfsq+R); + + val_hi = hi*ivln2hi; + val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; + + /* spadd(val_hi, val_lo, y), except for not using double_t: */ + y = k; + w = y + val_hi; + val_lo += (y - w) + val_hi; + val_hi = w; + + return val_lo + val_hi; +} diff --git a/system/lib/libc/musl/src/math/log_small.c b/system/lib/libc/musl/src/math/log_small.c new file mode 100644 index 0000000000000..e61e113d41af9 --- /dev/null +++ b/system/lib/libc/musl/src/math/log_small.c @@ -0,0 +1,118 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* log(x) + * Return the logarithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Remez algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +static const double +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +double log(double x) +{ + union {double f; uint64_t i;} u = {x}; + double_t hfsq,f,s,z,R,w,t1,t2,dk; + uint32_t hx; + int k; + + hx = u.i>>32; + k = 0; + if (hx < 0x00100000 || hx>>31) { + if (u.i<<1 == 0) + return -1/(x*x); /* log(+-0)=-inf */ + if (hx>>31) + return (x-x)/0.0; /* log(-#) = NaN */ + /* subnormal number, scale x up */ + k -= 54; + x *= 0x1p54; + u.f = x; + hx = u.i>>32; + } else if (hx >= 0x7ff00000) { + return x; + } else if (hx == 0x3ff00000 && u.i<<32 == 0) + return 0; + + /* reduce x into [sqrt(2)/2, sqrt(2)] */ + hx += 0x3ff00000 - 0x3fe6a09e; + k += (int)(hx>>20) - 0x3ff; + hx = (hx&0x000fffff) + 0x3fe6a09e; + u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); + x = u.f; + + f = x - 1.0; + hfsq = 0.5*f*f; + s = f/(2.0+f); + z = s*s; + w = z*z; + t1 = w*(Lg2+w*(Lg4+w*Lg6)); + t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + R = t2 + t1; + dk = k; + return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; +} diff --git a/system/lib/libc/musl/src/math/pow_small.c b/system/lib/libc/musl/src/math/pow_small.c new file mode 100644 index 0000000000000..b66f632d8eea9 --- /dev/null +++ b/system/lib/libc/musl/src/math/pow_small.c @@ -0,0 +1,328 @@ +/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. 1 ** (anything) is 1 + * 3. (anything except 1) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. -1 ** +-INF is 1 + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF, raise divbyzero + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF, raise divbyzero + * 14. -0 ** (+odd integer) is -0 + * 15. -0 ** (-odd integer) is -INF, raise divbyzero + * 16. +INF ** (+anything except 0,NAN) is +INF + * 17. +INF ** (-anything except 0,NAN) is +0 + * 18. -INF ** (+odd integer) is -INF + * 19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer) + * 20. (anything) ** 1 is (anything) + * 21. (anything) ** -1 is 1/(anything) + * 22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 23. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "libm.h" + +static const double +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, +/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +double pow(double x, double y) +{ + double z,ax,z_h,z_l,p_h,p_l; + double y1,t1,t2,r,s,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy; + uint32_t lx,ly; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; + + /* x**0 = 1, even if x is NaN */ + if ((iy|ly) == 0) + return 1.0; + /* 1**y = 1, even if y is NaN */ + if (hx == 0x3ff00000 && lx == 0) + return 1.0; + /* NaN if either arg is NaN */ + if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) || + iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 0)) + return x + y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x43400000) + yisint = 2; /* even integer y */ + else if (iy >= 0x3ff00000) { + k = (iy>>20) - 0x3ff; /* exponent */ + if (k > 20) { + j = ly>>(52-k); + if ((j<<(52-k)) == ly) + yisint = 2 - (j&1); + } else if (ly == 0) { + j = iy>>(20-k); + if ((j<<(20-k)) == iy) + yisint = 2 - (j&1); + } + } + } + + /* special value of y */ + if (ly == 0) { + if (iy == 0x7ff00000) { /* y is +-inf */ + if (((ix-0x3ff00000)|lx) == 0) /* (-1)**+-inf is 1 */ + return 1.0; + else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ + return hy >= 0 ? y : 0.0; + else /* (|x|<1)**+-inf = 0,inf */ + return hy >= 0 ? 0.0 : -y; + } + if (iy == 0x3ff00000) { /* y is +-1 */ + if (hy >= 0) + return x; + y = 1/x; +#if FLT_EVAL_METHOD!=0 + { + union {double f; uint64_t i;} u = {y}; + uint64_t i = u.i & -1ULL/2; + if (i>>52 == 0 && (i&(i-1))) + FORCE_EVAL((float)y); + } +#endif + return y; + } + if (hy == 0x40000000) /* y is 2 */ + return x*x; + if (hy == 0x3fe00000) { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if (lx == 0) { + if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */ + z = ax; + if (hy < 0) /* z = (1/|x|) */ + z = 1.0/z; + if (hx < 0) { + if (((ix-0x3ff00000)|yisint) == 0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + s = 1.0; /* sign of result */ + if (hx < 0) { + if (yisint == 0) /* (x<0)**(non-int) is NaN */ + return (x-x)/(x-x); + if (yisint == 1) /* (x<0)**(odd int) */ + s = -1.0; + } + + /* |y| is huge */ + if (iy > 0x41e00000) { /* if |y| > 2**31 */ + if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ + if (ix <= 0x3fefffff) + return hy < 0 ? huge*huge : tiny*tiny; + if (ix >= 0x3ff00000) + return hy > 0 ? huge*huge : tiny*tiny; + } + /* over/underflow if x is not close to one */ + if (ix < 0x3fefffff) + return hy < 0 ? s*huge*huge : s*tiny*tiny; + if (ix > 0x3ff00000) + return hy > 0 ? s*huge*huge : s*tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = ax - 1.0; /* t has 20 trailing zeros */ + w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l - w*ivln2; + t1 = u + v; + SET_LOW_WORD(t1, 0); + t2 = v - (t1-u); + } else { + double ss,s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00100000) { + ax *= two53; + n -= 53; + GET_HIGH_WORD(ix,ax); + } + n += ((ix)>>20) - 0x3ff; + j = ix & 0x000fffff; + /* determine interval */ + ix = j | 0x3ff00000; /* normalize ix */ + if (j <= 0x3988E) /* |x|>1)|0x20000000) + 0x00080000 + (k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = ss*ss; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+ss); + s2 = s_h*s_h; + t_h = 3.0 + s2 + r; + SET_LOW_WORD(t_h, 0); + t_l = r - ((t_h-3.0)-s2); + /* u+v = ss*(1+...) */ + u = s_h*t_h; + v = s_l*t_h + t_l*ss; + /* 2/(3log2)*(ss+...) */ + p_h = u + v; + SET_LOW_WORD(p_h, 0); + p_l = v - (p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp + dp_l[k]; + /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = ((z_h + z_l) + dp_h[k]) + t; + SET_LOW_WORD(t1, 0); + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + SET_LOW_WORD(y1, 0); + p_l = (y-y1)*t1 + y*t2; + p_h = y1*t1; + z = p_l + p_h; + EXTRACT_WORDS(j, i, z); + if (j >= 0x40900000) { /* z >= 1024 */ + if (((j-0x40900000)|i) != 0) /* if z > 1024 */ + return s*huge*huge; /* overflow */ + if (p_l + ovt > z - p_h) + return s*huge*huge; /* overflow */ + } else if ((j&0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ // FIXME: instead of abs(j) use unsigned j + if (((j-0xc090cc00)|i) != 0) /* z < -1075 */ + return s*tiny*tiny; /* underflow */ + if (p_l <= z - p_h) + return s*tiny*tiny; /* underflow */ + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i>>20) - 0x3ff; + n = 0; + if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j + (0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20) - 0x3ff; /* new k for n */ + t = 0.0; + SET_HIGH_WORD(t, n & ~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if (j < 0) + n = -n; + p_h -= t; + } + t = p_l + p_h; + SET_LOW_WORD(t, 0); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2 + t*lg2_l; + z = u + v; + w = v - (z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-2.0) - (w + z*w); + z = 1.0 - (r-z); + GET_HIGH_WORD(j, z); + j += n<<20; + if ((j>>20) <= 0) /* subnormal output */ + z = scalbn(z,n); + else + SET_HIGH_WORD(z, j); + return s*z; +} diff --git a/system/lib/libc/musl/src/math/rint.c b/system/lib/libc/musl/src/math/rint.c index fbba390e7d723..bd4c32f9f6d77 100644 --- a/system/lib/libc/musl/src/math/rint.c +++ b/system/lib/libc/musl/src/math/rint.c @@ -2,15 +2,22 @@ #include #include +#ifndef __wasm__ #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON #endif static const double_t toint = 1/EPS; +#endif double rint(double x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_rint(x); +#else union {double f; uint64_t i;} u = {x}; int e = u.i>>52 & 0x7ff; int s = u.i>>63; @@ -25,4 +32,5 @@ double rint(double x) if (y == 0) return s ? -0.0 : 0; return y; +#endif } diff --git a/system/lib/libc/musl/src/math/rintf.c b/system/lib/libc/musl/src/math/rintf.c index 9047688d246a6..59401f2bf75cb 100644 --- a/system/lib/libc/musl/src/math/rintf.c +++ b/system/lib/libc/musl/src/math/rintf.c @@ -2,6 +2,7 @@ #include #include +#ifndef __wasm__ #if FLT_EVAL_METHOD==0 #define EPS FLT_EPSILON #elif FLT_EVAL_METHOD==1 @@ -10,9 +11,15 @@ #define EPS LDBL_EPSILON #endif static const float_t toint = 1/EPS; +#endif float rintf(float x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_rintf(x); +#else union {float f; uint32_t i;} u = {x}; int e = u.i>>23 & 0xff; int s = u.i>>31; @@ -27,4 +34,5 @@ float rintf(float x) if (y == 0) return s ? -0.0f : 0.0f; return y; +#endif } diff --git a/system/lib/libc/musl/src/math/sqrt.c b/system/lib/libc/musl/src/math/sqrt.c index 5ba2655962135..6854c98381642 100644 --- a/system/lib/libc/musl/src/math/sqrt.c +++ b/system/lib/libc/musl/src/math/sqrt.c @@ -5,6 +5,7 @@ #define FENV_SUPPORT 1 +#ifndef __wasm__ /* returns a*b*2^-32 - e, with error 0 <= e < 1. */ static inline uint32_t mul32(uint32_t a, uint32_t b) { @@ -20,9 +21,15 @@ static inline uint64_t mul64(uint64_t a, uint64_t b) uint64_t blo = b&0xffffffff; return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32); } +#endif double sqrt(double x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_sqrt(x); +#else uint64_t ix, top, m; /* special case handling. */ @@ -155,4 +162,5 @@ double sqrt(double x) y = eval_as_double(y + t); } return y; +#endif } diff --git a/system/lib/libc/musl/src/math/sqrtf.c b/system/lib/libc/musl/src/math/sqrtf.c index 740d81cbab421..fd74702691215 100644 --- a/system/lib/libc/musl/src/math/sqrtf.c +++ b/system/lib/libc/musl/src/math/sqrtf.c @@ -3,17 +3,24 @@ #include "libm.h" #include "sqrt_data.h" +#ifndef __wasm__ #define FENV_SUPPORT 1 static inline uint32_t mul32(uint32_t a, uint32_t b) { return (uint64_t)a*b >> 32; } +#endif /* see sqrt.c for more detailed comments. */ float sqrtf(float x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_sqrtf(x); +#else uint32_t ix, m, m1, m0, even, ey; ix = asuint(x); @@ -80,4 +87,5 @@ float sqrtf(float x) y = eval_as_float(y + t); } return y; +#endif } diff --git a/system/lib/libc/musl/src/math/sqrtl.c b/system/lib/libc/musl/src/math/sqrtl.c index a231b3f2016b3..81e68fea20c39 100644 --- a/system/lib/libc/musl/src/math/sqrtl.c +++ b/system/lib/libc/musl/src/math/sqrtl.c @@ -176,6 +176,10 @@ static inline u128 mul128_tail(u128 a, u128 b) /* see sqrt.c for detailed comments. */ +#ifdef __EMSCRIPTEN__ +// https://github.com/emscripten-core/emscripten/issues/15655 +__attribute__((no_sanitize("address"))) +#endif long double sqrtl(long double x) { u128 ix, ml; diff --git a/system/lib/libc/musl/src/math/trunc.c b/system/lib/libc/musl/src/math/trunc.c index d13711b5015e0..c6d25ec1b456e 100644 --- a/system/lib/libc/musl/src/math/trunc.c +++ b/system/lib/libc/musl/src/math/trunc.c @@ -2,6 +2,11 @@ double trunc(double x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_trunc(x); +#else union {double f; uint64_t i;} u = {x}; int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12; uint64_t m; @@ -16,4 +21,5 @@ double trunc(double x) FORCE_EVAL(x + 0x1p120f); u.i &= ~m; return u.f; +#endif } diff --git a/system/lib/libc/musl/src/math/truncf.c b/system/lib/libc/musl/src/math/truncf.c index 1a7d03c3bce10..3c9f7f4661736 100644 --- a/system/lib/libc/musl/src/math/truncf.c +++ b/system/lib/libc/musl/src/math/truncf.c @@ -2,6 +2,11 @@ float truncf(float x) { +// XXX EMSCRIPTEN: use the wasm instruction via clang builtin +// See https://github.com/emscripten-core/emscripten/issues/9236 +#ifdef __wasm__ + return __builtin_truncf(x); +#else union {float f; uint32_t i;} u = {x}; int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9; uint32_t m; @@ -16,4 +21,5 @@ float truncf(float x) FORCE_EVAL(x + 0x1p120f); u.i &= ~m; return u.f; +#endif } diff --git a/system/lib/libc/musl/src/misc/getentropy.c b/system/lib/libc/musl/src/misc/getentropy.c index 651ea95f14310..c42689f427530 100644 --- a/system/lib/libc/musl/src/misc/getentropy.c +++ b/system/lib/libc/musl/src/misc/getentropy.c @@ -4,6 +4,10 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif + int getentropy(void *buffer, size_t len) { int cs, ret = 0; @@ -14,6 +18,9 @@ int getentropy(void *buffer, size_t len) return -1; } +#ifdef __EMSCRIPTEN__ + ret = __wasi_syscall_ret(__wasi_random_get(buffer, len)); +#else pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); while (len) { @@ -28,6 +35,7 @@ int getentropy(void *buffer, size_t len) } pthread_setcancelstate(cs, 0); +#endif return ret; } diff --git a/system/lib/libc/musl/src/misc/getopt.c b/system/lib/libc/musl/src/misc/getopt.c index b02b81c34329b..b08abbc96871b 100644 --- a/system/lib/libc/musl/src/misc/getopt.c +++ b/system/lib/libc/musl/src/misc/getopt.c @@ -16,7 +16,7 @@ weak_alias(__optreset, optreset); void __getopt_msg(const char *a, const char *b, const char *c, size_t l) { FILE *f = stderr; - b = __lctrans_cur(b); + b = LCTRANS_CUR(b); /* XXX EMSCRIPTEN: Use macro version here */ FLOCK(f); fputs(a, f)>=0 && fwrite(b, strlen(b), 1, f) diff --git a/system/lib/libc/musl/src/misc/ioctl.c b/system/lib/libc/musl/src/misc/ioctl.c index 35804f026ef68..0dd521ad58dfe 100644 --- a/system/lib/libc/musl/src/misc/ioctl.c +++ b/system/lib/libc/musl/src/misc/ioctl.c @@ -9,7 +9,12 @@ #include #include "syscall.h" +#ifdef __EMSCRIPTEN__ +// The upstream version below is UB in C2x and rejected by clang. +#define alignof(t) _Alignof(t) +#else #define alignof(t) offsetof(struct { char c; t x; }, x) +#endif #define W 1 #define R 2 diff --git a/system/lib/libc/musl/src/mman/mmap.c b/system/lib/libc/musl/src/mman/mmap.c index 43e5e02941dc7..c755ca849eff4 100644 --- a/system/lib/libc/musl/src/mman/mmap.c +++ b/system/lib/libc/musl/src/mman/mmap.c @@ -37,3 +37,4 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off) } weak_alias(__mmap, mmap); +weak_alias(__mmap, emscripten_builtin_mmap); diff --git a/system/lib/libc/musl/src/mman/munmap.c b/system/lib/libc/musl/src/mman/munmap.c index 2bf83bbe9b702..083e77285ee3a 100644 --- a/system/lib/libc/musl/src/mman/munmap.c +++ b/system/lib/libc/musl/src/mman/munmap.c @@ -11,3 +11,4 @@ int __munmap(void *start, size_t len) } weak_alias(__munmap, munmap); +weak_alias(__munmap, emscripten_builtin_munmap); diff --git a/system/lib/libc/musl/src/multibyte/mbsrtowcs.c b/system/lib/libc/musl/src/multibyte/mbsrtowcs.c index 9b2f2dfbb023b..32d74154f84d1 100644 --- a/system/lib/libc/musl/src/multibyte/mbsrtowcs.c +++ b/system/lib/libc/musl/src/multibyte/mbsrtowcs.c @@ -38,7 +38,8 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs } if (!ws) for (;;) { -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) typedef uint32_t __attribute__((__may_alias__)) w32; if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { while (!(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) { @@ -72,7 +73,8 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs *src = (const void *)s; return wn0; } -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) typedef uint32_t __attribute__((__may_alias__)) w32; if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { while (wn>=5 && !(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) { diff --git a/system/lib/libc/musl/src/network/freeaddrinfo.c b/system/lib/libc/musl/src/network/freeaddrinfo.c index 62241c239e27f..c4016d9f7c246 100644 --- a/system/lib/libc/musl/src/network/freeaddrinfo.c +++ b/system/lib/libc/musl/src/network/freeaddrinfo.c @@ -6,6 +6,13 @@ void freeaddrinfo(struct addrinfo *p) { +#if __EMSCRIPTEN__ + // Emscripten's usage of this structure is very simple: we always allocate + // ai_addr, and do not use the linked list aspect at all. There is also no + // aliasing with aibuf. + free(p->ai_addr); + free(p); +#else size_t cnt; for (cnt=1; p->ai_next; cnt++, p=p->ai_next); struct aibuf *b = (void *)((char *)p - offsetof(struct aibuf, ai)); @@ -13,4 +20,5 @@ void freeaddrinfo(struct addrinfo *p) LOCK(b->lock); if (!(b->ref -= cnt)) free(b); else UNLOCK(b->lock); +#endif } diff --git a/system/lib/libc/musl/src/network/if_indextoname.c b/system/lib/libc/musl/src/network/if_indextoname.c index 3b368bf0d1329..830e1a2dac159 100644 --- a/system/lib/libc/musl/src/network/if_indextoname.c +++ b/system/lib/libc/musl/src/network/if_indextoname.c @@ -14,7 +14,11 @@ char *if_indextoname(unsigned index, char *name) if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0; ifr.ifr_ifindex = index; r = ioctl(fd, SIOCGIFNAME, &ifr); +#ifdef __EMSCRIPTEN__ + __wasi_fd_close(fd); +#else __syscall(SYS_close, fd); +#endif if (r < 0) { if (errno == ENODEV) errno = ENXIO; return 0; diff --git a/system/lib/libc/musl/src/network/if_nametoindex.c b/system/lib/libc/musl/src/network/if_nametoindex.c index 331413c68912d..5d61e579b3b61 100644 --- a/system/lib/libc/musl/src/network/if_nametoindex.c +++ b/system/lib/libc/musl/src/network/if_nametoindex.c @@ -13,6 +13,10 @@ unsigned if_nametoindex(const char *name) if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0; strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); r = ioctl(fd, SIOCGIFINDEX, &ifr); +#ifdef __EMSCRIPTEN__ + __wasi_fd_close(fd); +#else __syscall(SYS_close, fd); +#endif return r < 0 ? 0 : ifr.ifr_ifindex; } diff --git a/system/lib/libc/musl/src/network/netlink.c b/system/lib/libc/musl/src/network/netlink.c index 94dba7f5c9e40..676b65cde3972 100644 --- a/system/lib/libc/musl/src/network/netlink.c +++ b/system/lib/libc/musl/src/network/netlink.c @@ -47,6 +47,10 @@ int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct if (fd < 0) return -1; r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx); if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx); +#ifdef __EMSCRIPTEN__ + __wasi_fd_close(fd); +#else __syscall(SYS_close,fd); +#endif return r; } diff --git a/system/lib/libc/musl/src/network/ns_parse.c b/system/lib/libc/musl/src/network/ns_parse.c index d01da47a3d411..71bd309cfdc7f 100644 --- a/system/lib/libc/musl/src/network/ns_parse.c +++ b/system/lib/libc/musl/src/network/ns_parse.c @@ -47,6 +47,30 @@ void ns_put32(unsigned long l, unsigned char *cp) *cp++ = l; } +int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count) +{ + const unsigned char *p = ptr; + int r; + + while (count--) { + r = dn_skipname(p, eom); + if (r < 0) goto bad; + if (r + 2 * NS_INT16SZ > eom - p) goto bad; + p += r + 2 * NS_INT16SZ; + if (section != ns_s_qd) { + if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad; + p += NS_INT32SZ; + NS_GET16(r, p); + if (r > eom - p) goto bad; + p += r; + } + } + return p - ptr; +bad: + errno = EMSGSIZE; + return -1; +} + int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle) { int i, r; @@ -77,35 +101,20 @@ int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle) return -1; } -int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count) +int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom, + const unsigned char *src, char *dst, size_t dstsiz) { - const unsigned char *p = ptr; int r; - - while (count--) { - r = dn_skipname(p, eom); - if (r < 0) goto bad; - if (r + 2 * NS_INT16SZ > eom - p) goto bad; - p += r + 2 * NS_INT16SZ; - if (section != ns_s_qd) { - if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad; - p += NS_INT32SZ; - NS_GET16(r, p); - if (r > eom - p) goto bad; - p += r; - } - } - return p - ptr; -bad: - errno = EMSGSIZE; - return -1; + r = dn_expand(msg, eom, src, dst, dstsiz); + if (r < 0) errno = EMSGSIZE; + return r; } int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) { int r; - if (section < 0 || section >= ns_s_max) goto bad; + if (section >= ns_s_max) goto bad; if (section != handle->_sect) { handle->_sect = section; handle->_rrnum = 0; @@ -160,12 +169,3 @@ int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) return -1; } -int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom, - const unsigned char *src, char *dst, size_t dstsiz) -{ - int r; - r = dn_expand(msg, eom, src, dst, dstsiz); - if (r < 0) errno = EMSGSIZE; - return r; -} - diff --git a/system/lib/libc/musl/src/network/recvmmsg.c b/system/lib/libc/musl/src/network/recvmmsg.c index 2978e2f64f34e..7ef9ad1894ec6 100644 --- a/system/lib/libc/musl/src/network/recvmmsg.c +++ b/system/lib/libc/musl/src/network/recvmmsg.c @@ -12,7 +12,7 @@ hidden void __convert_scm_timestamps(struct msghdr *, socklen_t); int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec *timeout) { -#if LONG_MAX > INT_MAX +#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) struct mmsghdr *mh = msgvec; unsigned int i; for (i = vlen; i; i--, mh++) diff --git a/system/lib/libc/musl/src/network/recvmsg.c b/system/lib/libc/musl/src/network/recvmsg.c index 03641625e8af7..a973763a85a2e 100644 --- a/system/lib/libc/musl/src/network/recvmsg.c +++ b/system/lib/libc/musl/src/network/recvmsg.c @@ -51,7 +51,7 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) { ssize_t r; socklen_t orig_controllen = msg->msg_controllen; -#if LONG_MAX > INT_MAX +#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) struct msghdr h, *orig = msg; if (msg) { h = *msg; @@ -61,7 +61,7 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags) #endif r = socketcall_cp(recvmsg, fd, msg, flags, 0, 0, 0); if (r >= 0) __convert_scm_timestamps(msg, orig_controllen); -#if LONG_MAX > INT_MAX +#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) if (orig) *orig = h; #endif return r; diff --git a/system/lib/libc/musl/src/network/res_msend.c b/system/lib/libc/musl/src/network/res_msend.c index fcb52513002a2..efe86a38a2c5d 100644 --- a/system/lib/libc/musl/src/network/res_msend.c +++ b/system/lib/libc/musl/src/network/res_msend.c @@ -19,7 +19,11 @@ static void cleanup(void *p) { struct pollfd *pfd = p; for (int i=0; pfd[i].fd >= -1; i++) +#ifdef __EMSCRIPTEN__ + if (pfd[i].fd >= 0) __wasi_fd_close((intptr_t)pfd[i].fd); +#else if (pfd[i].fd >= 0) __syscall(SYS_close, pfd[i].fd); +#endif } static unsigned long mtime() @@ -303,7 +307,11 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries, * Immediately close TCP socket so as not to consume * resources we no longer need. */ alens[i] = alen; +#ifdef __EMSCRIPTEN__ + __wasi_fd_close((intptr_t)pfd[i].fd); +#else __syscall(SYS_close, pfd[i].fd); +#endif pfd[i].fd = -1; } } diff --git a/system/lib/libc/musl/src/network/sendmsg.c b/system/lib/libc/musl/src/network/sendmsg.c index acdfdf29247f0..fbdc00e07377f 100644 --- a/system/lib/libc/musl/src/network/sendmsg.c +++ b/system/lib/libc/musl/src/network/sendmsg.c @@ -6,7 +6,7 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) { -#if LONG_MAX > INT_MAX +#if LONG_MAX > INT_MAX && !defined(__EMSCRIPTEN__) struct msghdr h; /* Kernels before 2.6.38 set SCM_MAX_FD to 255, allocate enough * space to support an SCM_RIGHTS ancillary message with 255 fds. diff --git a/system/lib/libc/musl/src/process/fexecve.c b/system/lib/libc/musl/src/process/fexecve.c index 554c1981b670f..37fb294482093 100644 --- a/system/lib/libc/musl/src/process/fexecve.c +++ b/system/lib/libc/musl/src/process/fexecve.c @@ -6,8 +6,10 @@ int fexecve(int fd, char *const argv[], char *const envp[]) { +#ifndef __EMSCRIPTEN__ int r = __syscall(SYS_execveat, fd, "", argv, envp, AT_EMPTY_PATH); if (r != -ENOSYS) return __syscall_ret(r); +#endif char buf[15 + 3*sizeof(int)]; __procfdname(buf, fd); execve(buf, argv, envp); diff --git a/system/lib/libc/musl/src/sched/sched_yield.c b/system/lib/libc/musl/src/sched/sched_yield.c index ee6f0e7f16041..7bd3846fc239e 100644 --- a/system/lib/libc/musl/src/sched/sched_yield.c +++ b/system/lib/libc/musl/src/sched/sched_yield.c @@ -1,7 +1,21 @@ #include #include "syscall.h" +#if __EMSCRIPTEN__ +#include +#include +#include "threading_internal.h" +#endif + int sched_yield() { +#if __EMSCRIPTEN__ + // SharedArrayBuffer and wasm threads do not support explicit yielding. + // For now we at least call `emscripten_yield` which processes the event queue + // (along with other essential tasks). + _emscripten_yield(emscripten_get_now()); + return 0; +#else return syscall(SYS_sched_yield); +#endif } diff --git a/system/lib/libc/musl/src/select/ppoll.c b/system/lib/libc/musl/src/select/ppoll.c index 9a0bf929584d7..3b2d51133d415 100644 --- a/system/lib/libc/musl/src/select/ppoll.c +++ b/system/lib/libc/musl/src/select/ppoll.c @@ -9,6 +9,16 @@ int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_t *mask) { +#ifdef __EMSCRIPTEN__ + // Emscripten does not support true async signals so we just implement ppoll + // in terms of poll here in userspace. + int timeout = (to == NULL) ? -1 : (to->tv_sec * 1000 + to->tv_nsec / 1000000); + sigset_t origmask; + if (mask) pthread_sigmask(SIG_SETMASK, mask, &origmask); + int rtn = poll(fds, n, timeout); + if (mask) pthread_sigmask(SIG_SETMASK, &origmask, NULL); + return rtn; +#else time_t s = to ? to->tv_sec : 0; long ns = to ? to->tv_nsec : 0; #ifdef SYS_ppoll_time64 @@ -23,4 +33,5 @@ int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_ #endif return syscall_cp(SYS_ppoll, fds, n, to ? ((long[]){s, ns}) : 0, mask, _NSIG/8); +#endif } diff --git a/system/lib/libc/musl/src/select/pselect.c b/system/lib/libc/musl/src/select/pselect.c index 54cfb291bba2c..519a770b80657 100644 --- a/system/lib/libc/musl/src/select/pselect.c +++ b/system/lib/libc/musl/src/select/pselect.c @@ -9,6 +9,20 @@ int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec *restrict ts, const sigset_t *restrict mask) { +#ifdef __EMSCRIPTEN__ + // Emscripten does not support true async signals so we just implement pselect + // in terms of select here in userspace. + struct timeval tv_timeout; + if (ts) { + tv_timeout.tv_sec = ts->tv_sec; + tv_timeout.tv_usec = ts->tv_nsec / 1000; + } + sigset_t origmask; + if (mask) pthread_sigmask(SIG_SETMASK, mask, &origmask); + int rtn = select(n, rfds, wfds, efds, ts ? &tv_timeout : NULL); + if (mask) pthread_sigmask(SIG_SETMASK, &origmask, NULL); + return rtn; +#else syscall_arg_t data[2] = { (uintptr_t)mask, _NSIG/8 }; time_t s = ts ? ts->tv_sec : 0; long ns = ts ? ts->tv_nsec : 0; @@ -23,4 +37,5 @@ int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restric #endif return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, ts ? ((long[]){s, ns}) : 0, data); +#endif } diff --git a/system/lib/libc/musl/src/select/select.c b/system/lib/libc/musl/src/select/select.c index f1d72863c6759..8b5b533359761 100644 --- a/system/lib/libc/musl/src/select/select.c +++ b/system/lib/libc/musl/src/select/select.c @@ -7,6 +7,12 @@ #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) +#ifdef __EMSCRIPTEN__ +#include +#include +static int emscripten_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv); +#endif + int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv) { time_t s = tv ? tv->tv_sec : 0; @@ -15,6 +21,9 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1; if (s<0 || us<0) return __syscall_ret(-EINVAL); +#ifdef __EMSCRIPTEN__ + return emscripten_select(n, rfds, wfds, efds, tv); +#else if (us/1000000 > max_time - s) { s = max_time; us = 999999; @@ -24,7 +33,6 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict us %= 1000000; ns = us*1000; } - #ifdef SYS_pselect6_time64 int r = -ENOSYS; if (SYS_pselect6 == SYS_pselect6_time64 || !IS32BIT(s)) @@ -42,4 +50,79 @@ int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? ((long[]){s, ns}) : 0, ((syscall_arg_t[]){ 0, _NSIG/8 })); #endif +#endif } + +#ifdef __EMSCRIPTEN__ +static int emscripten_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv) +{ + // Implement select in terms of `poll()` + + // Part 1: convert select arguments into poll arguments + + time_t s = tv ? tv->tv_sec : 0; + suseconds_t us = tv ? tv->tv_usec : 0; + int timeout = tv ? s * 1000 + (us / 1000) : -1; + int n = 0; + struct pollfd* fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd)); + + for (int i = 0; i < nfds; i++) { + if (readfds && FD_ISSET(i, readfds)) { + fds[n].events |= POLLIN; + } + if (writefds && FD_ISSET(i, writefds)) { + fds[n].events |= POLLOUT; + } + if (exceptfds && FD_ISSET(i, exceptfds)) { + fds[n].events |= POLLPRI; + } + if (fds[n].events) { + fds[n].fd = i; + n++; + } + } + + int rtn = __syscall_poll((intptr_t)fds, n, timeout); + if (rtn < 0) { + free(fds); + return -1; + } + + // Part 2: Translate the result of poll into the results of select(); + + if (readfds) FD_ZERO(readfds); + if (writefds) FD_ZERO(writefds); + if (exceptfds) FD_ZERO(exceptfds); + + int count = 0; + + if (rtn > 0) { + for (int i = 0; i < n; i++) { + int fd = fds[i].fd; + short revents = fds[i].revents; + if (revents) { + // Map POLLIN to readfds + // POLLHUP/POLLERR usually count as readable (EOF or Error) + if (readfds && (revents & POLLIN || revents & POLLHUP || revents & POLLERR)) { + FD_SET(fd, readfds); + count++; + } + // Map POLLOUT to writefds + // POLLERR usually counts as writable (so write fails immediately) + if (writefds && (revents & POLLOUT || revents & POLLERR)) { + FD_SET(fd, writefds); + count++; + } + // Map POLLPRI to exceptfds + if (exceptfds && (revents & POLLPRI)) { + FD_SET(fd, exceptfds); + count++; + } + } + } + } + + free(fds); + return count; +} +#endif diff --git a/system/lib/libc/musl/src/signal/block.c b/system/lib/libc/musl/src/signal/block.c index cc8698f0bb7fb..736084bc10d27 100644 --- a/system/lib/libc/musl/src/signal/block.c +++ b/system/lib/libc/musl/src/signal/block.c @@ -30,15 +30,21 @@ static const unsigned long app_mask[] = { void __block_all_sigs(void *set) { +#ifndef __EMSCRIPTEN__ __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8); +#endif } void __block_app_sigs(void *set) { +#ifndef __EMSCRIPTEN__ __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8); +#endif } void __restore_sigs(void *set) { +#ifndef __EMSCRIPTEN__ __syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8); +#endif } diff --git a/system/lib/libc/musl/src/signal/getitimer.c b/system/lib/libc/musl/src/signal/getitimer.c index 36d1eb9dc6e99..251b2064fa202 100644 --- a/system/lib/libc/musl/src/signal/getitimer.c +++ b/system/lib/libc/musl/src/signal/getitimer.c @@ -1,8 +1,18 @@ #include #include "syscall.h" +#ifdef __EMSCRIPTEN__ +#include +void __getitimer(int which, struct itimerval *old, double now); +#endif + int getitimer(int which, struct itimerval *old) { +#ifdef __EMSCRIPTEN__ + if (which > ITIMER_PROF) return EINVAL; + __getitimer(which, old, emscripten_get_now()); + return 0; +#else if (sizeof(time_t) > sizeof(long)) { long old32[4]; int r = __syscall(SYS_getitimer, which, old32); @@ -15,4 +25,5 @@ int getitimer(int which, struct itimerval *old) return __syscall_ret(r); } return syscall(SYS_getitimer, which, old); +#endif } diff --git a/system/lib/libc/musl/src/signal/setitimer.c b/system/lib/libc/musl/src/signal/setitimer.c index 0dfbeb4db5a7a..94cc9c40326a8 100644 --- a/system/lib/libc/musl/src/signal/setitimer.c +++ b/system/lib/libc/musl/src/signal/setitimer.c @@ -4,8 +4,123 @@ #define IS32BIT(x) !((x)+0x80000000ULL>>32) +#ifdef __EMSCRIPTEN__ +#include +#include +#include +#include +#include +#include +#include + +#include "emscripten_internal.h" + +// Timeouts can either fire directly from the JS event loop (which calls +// `_emscripten_timeout`), or from `_emscripten_check_timers` (which is called +// from `_emscripten_yield`). In order to be able to check the timers here we +// cache the current timeout and interval for each the 3 types of timer +// (ITIMER_PROF/ITIMER_VIRTUAL/ITIMER_REAL). +static double current_timeout_ms[3]; +static double current_intervals_ms[3]; + +#define MAX(a,b) ((a)>(b)?(a):(b)) + +void __getitimer(int which, struct itimerval *old, double now) +{ + double remaining_ms = MAX(current_timeout_ms[which] - now, 0); + old->it_value.tv_sec = remaining_ms / 1000; + old->it_value.tv_usec = remaining_ms * 1000; + old->it_interval.tv_sec = current_intervals_ms[which] / 1000; + old->it_interval.tv_usec = current_intervals_ms[which] * 1000; +} + +void _emscripten_timeout(int which, double now) +{ + int signum = SIGALRM; + if (which == ITIMER_PROF) + signum = SIGPROF; + else if (which == ITIMER_VIRTUAL) + signum = SIGVTALRM; + double next_timeout = 0.0; + if (current_intervals_ms[which]) { + // If time went backwards, schedule the next timer as if it didn't. + now = __builtin_wasm_max_f64(now, current_timeout_ms[which]); + // The next alarm is due 'interval' ms after the previous one. + // If this alarm was delayed, that is sooner than 'interval' ms + // from now. The delay could even be so long that we missed the + // next alarm(s) entirely. Schedule the alarm for the next + // multiple of 'interval' ms from the original due time. + uint64_t intervals = + (uint64_t)(now - current_timeout_ms[which]) / + (uint64_t)current_intervals_ms[which] + + 1; + current_timeout_ms[which] += + intervals * current_intervals_ms[which]; + next_timeout = current_timeout_ms[which] - now; + } else { + current_timeout_ms[which] = 0; + } + _setitimer_js(which, next_timeout); + raise(signum); +} + +bool _emscripten_check_timers(double now) +{ + // Timers always run on the main runtime thread. They are registered with + // _setitimer_js which is proxied to the main runtime thread. + assert(emscripten_is_main_runtime_thread()); + bool rtn = false; + for (int which = 0; which < 3; which++) { + if (current_timeout_ms[which]) { + // Only call out to JS to get the current time if it was not passed in + // *and* we have one or more timers set. + if (!now) + now = emscripten_get_now(); + if (now >= current_timeout_ms[which]) { + rtn = true; + _emscripten_timeout(which, now); + } + } + } + return rtn; +} + +double _emscripten_next_timer() +{ + assert(emscripten_is_main_runtime_thread()); + double next_timer = INFINITY; + for (int which = 0; which < 3; which++) { + if (current_timeout_ms[which]) { + next_timer = fmin(current_timeout_ms[which], next_timer); + } + } + // Avoid calling emscripten_get_now() unless we need to here. + if (next_timer != INFINITY) { + next_timer -= emscripten_get_now(); + } + return next_timer; +} +#endif + int setitimer(int which, const struct itimerval *restrict new, struct itimerval *restrict old) { +#ifdef __EMSCRIPTEN__ + if (which > ITIMER_PROF) return EINVAL; + double now = emscripten_get_now(); + if (old) { + __getitimer(which, old, now); + } + double timeout_ms = new->it_value.tv_sec * 1000 + new->it_value.tv_usec / 1000.0; + double interval_ms = new->it_interval.tv_sec * 1000 + new->it_interval.tv_usec / 1000.0; + if (new->it_value.tv_sec || new->it_value.tv_usec) { + current_timeout_ms[which] = now + timeout_ms; + current_intervals_ms[which] = interval_ms; + } else { + current_timeout_ms[which] = 0; + current_intervals_ms[which] = 0; + } + return _setitimer_js(which, timeout_ms); +#else if (sizeof(time_t) > sizeof(long)) { time_t is = new->it_interval.tv_sec, vs = new->it_value.tv_sec; long ius = new->it_interval.tv_usec, vus = new->it_value.tv_usec; @@ -23,4 +138,5 @@ int setitimer(int which, const struct itimerval *restrict new, struct itimerval return __syscall_ret(r); } return syscall(SYS_setitimer, which, new, old); +#endif } diff --git a/system/lib/libc/musl/src/stat/fchmod.c b/system/lib/libc/musl/src/stat/fchmod.c index 7a503eefc46ef..58badd5c01bb8 100644 --- a/system/lib/libc/musl/src/stat/fchmod.c +++ b/system/lib/libc/musl/src/stat/fchmod.c @@ -1,3 +1,6 @@ +#ifdef __EMSCRIPTEN__ +#include +#endif #include #include #include @@ -6,8 +9,13 @@ int fchmod(int fd, mode_t mode) { int ret = __syscall(SYS_fchmod, fd, mode); +#if __EMSCRIPTEN__ + if (ret != -EBADF || !__wasi_fd_is_valid(fd)) + return __syscall_ret(ret); +#else if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); +#endif char buf[15+3*sizeof(int)]; __procfdname(buf, fd); diff --git a/system/lib/libc/musl/src/stat/fchmodat.c b/system/lib/libc/musl/src/stat/fchmodat.c index 92c9d1b0e4a2c..4a4539f05c89c 100644 --- a/system/lib/libc/musl/src/stat/fchmodat.c +++ b/system/lib/libc/musl/src/stat/fchmodat.c @@ -5,7 +5,9 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag) { +#ifndef __EMSCRIPTEN__ if (!flag) return syscall(SYS_fchmodat, fd, path, mode); +#endif int ret = __syscall(SYS_fchmodat2, fd, path, mode, flag); if (ret != -ENOSYS) return __syscall_ret(ret); @@ -32,9 +34,17 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag) ret = stat(proc, &st); if (!ret) { if (S_ISLNK(st.st_mode)) ret = __syscall_ret(-EOPNOTSUPP); +#ifdef __EMSCRIPTEN__ + else ret = syscall(SYS_fchmodat2, AT_FDCWD, proc, mode, 0); +#else else ret = syscall(SYS_fchmodat, AT_FDCWD, proc, mode); +#endif } +#ifdef __EMSCRIPTEN__ + __wasi_fd_close(fd2); +#else __syscall(SYS_close, fd2); +#endif return ret; } diff --git a/system/lib/libc/musl/src/stat/fstatat.c b/system/lib/libc/musl/src/stat/fstatat.c index 9eed063b26bcf..631451268c590 100644 --- a/system/lib/libc/musl/src/stat/fstatat.c +++ b/system/lib/libc/musl/src/stat/fstatat.c @@ -7,6 +7,11 @@ #include #include "syscall.h" +/* XXX Emscripten: We #define kstat to stat so we can simply make the syscall + * without the extra copy. + * See arch/emscripten/kstat.h + */ +#ifndef __EMSCRIPTEN__ struct statx { uint32_t stx_mask; uint32_t stx_blksize; @@ -135,10 +140,22 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric return 0; } #endif +#endif int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag) { int ret; +#ifdef __EMSCRIPTEN__ + // some logic here copied from fstatat_kstat above + if (flag==AT_EMPTY_PATH && fd>=0 && !*path) + ret = __syscall(SYS_fstat, fd, st); + else if ((fd == AT_FDCWD || *path=='/') && !flag) + ret = __syscall(SYS_stat, path, st); + else if ((fd == AT_FDCWD || *path=='/') && flag==AT_SYMLINK_NOFOLLOW) + ret = __syscall(SYS_lstat, path, st); + else + ret = __syscall(SYS_fstatat, fd, path, st, flag); +#else #ifdef SYS_fstatat if (sizeof((struct kstat){0}.st_atime_sec) < sizeof(time_t)) { ret = fstatat_statx(fd, path, st, flag); @@ -147,6 +164,7 @@ int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int f ret = fstatat_kstat(fd, path, st, flag); #else ret = fstatat_statx(fd, path, st, flag); +#endif #endif return __syscall_ret(ret); } diff --git a/system/lib/libc/musl/src/stdio/__fdopen.c b/system/lib/libc/musl/src/stdio/__fdopen.c index 116e78e56d2a1..ffc4df718a0b8 100644 --- a/system/lib/libc/musl/src/stdio/__fdopen.c +++ b/system/lib/libc/musl/src/stdio/__fdopen.c @@ -26,8 +26,10 @@ FILE *__fdopen(int fd, const char *mode) /* Impose mode restrictions */ if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD; +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process /* Apply close-on-exec flag */ if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); +#endif /* Set append mode on fd if opened for append */ if (*mode == 'a') { diff --git a/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c b/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c index 183a5d5538955..2f3acb831388e 100644 --- a/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c +++ b/system/lib/libc/musl/src/stdio/__fopen_rb_ca.c @@ -8,7 +8,9 @@ FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t le f->fd = sys_open(filename, O_RDONLY|O_CLOEXEC); if (f->fd < 0) return 0; +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process __syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC); +#endif f->flags = F_NOWR | F_PERM; f->buf = buf + UNGET; diff --git a/system/lib/libc/musl/src/stdio/__lockfile.c b/system/lib/libc/musl/src/stdio/__lockfile.c index 0f60a14990943..3300a3c25495b 100644 --- a/system/lib/libc/musl/src/stdio/__lockfile.c +++ b/system/lib/libc/musl/src/stdio/__lockfile.c @@ -3,7 +3,8 @@ int __lockfile(FILE *f) { - int owner = f->lock, tid = __pthread_self()->tid; +#ifdef __EMSCRIPTEN_SHARED_MEMORY__ + int owner = f->lock, tid = CURRENT_THREAD_ID; if ((owner & ~MAYBE_WAITERS) == tid) return 0; owner = a_cas(&f->lock, 0, tid); @@ -13,11 +14,14 @@ int __lockfile(FILE *f) a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner) __futexwait(&f->lock, owner|MAYBE_WAITERS, 1); } +#endif return 1; } void __unlockfile(FILE *f) { +#ifdef __EMSCRIPTEN_SHARED_MEMORY__ if (a_swap(&f->lock, 0) & MAYBE_WAITERS) __wake(&f->lock, 1, 1); +#endif } diff --git a/system/lib/libc/musl/src/stdio/__stdio_close.c b/system/lib/libc/musl/src/stdio/__stdio_close.c index 3029132851878..7618de9309f32 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_close.c +++ b/system/lib/libc/musl/src/stdio/__stdio_close.c @@ -10,5 +10,9 @@ weak_alias(dummy, __aio_close); int __stdio_close(FILE *f) { +#ifdef __EMSCRIPTEN__ + return __wasi_syscall_ret(__wasi_fd_close(__aio_close(f->fd))); +#else return syscall(SYS_close, __aio_close(f->fd)); +#endif } diff --git a/system/lib/libc/musl/src/stdio/__stdio_read.c b/system/lib/libc/musl/src/stdio/__stdio_read.c index ea675da34abbf..392a4858281f3 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_read.c +++ b/system/lib/libc/musl/src/stdio/__stdio_read.c @@ -9,8 +9,16 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) }; ssize_t cnt; +#if __EMSCRIPTEN__ + size_t num; + if (__wasi_syscall_ret(__wasi_fd_read(f->fd, (struct __wasi_iovec_t*)iov, 2, &num))) { + num = -1; + } + cnt = num; +#else cnt = iov[0].iov_len ? syscall(SYS_readv, f->fd, iov, 2) : syscall(SYS_read, f->fd, iov[1].iov_base, iov[1].iov_len); +#endif if (cnt <= 0) { f->flags |= cnt ? F_ERR : F_EOF; return 0; diff --git a/system/lib/libc/musl/src/stdio/__stdio_write.c b/system/lib/libc/musl/src/stdio/__stdio_write.c index 5356553d54e86..7a125b89b928d 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_write.c +++ b/system/lib/libc/musl/src/stdio/__stdio_write.c @@ -17,7 +17,15 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) iovcnt--; } for (;;) { +#if __EMSCRIPTEN__ + size_t num; + if (__wasi_syscall_ret(__wasi_fd_write(f->fd, (struct __wasi_ciovec_t*)iov, iovcnt, &num))) { + num = -1; + } + cnt = num; +#else cnt = syscall(SYS_writev, f->fd, iov, iovcnt); +#endif if (cnt == rem) { f->wend = f->buf + f->buf_size; f->wpos = f->wbase = f->buf; diff --git a/system/lib/libc/musl/src/stdio/fopen.c b/system/lib/libc/musl/src/stdio/fopen.c index 80bc341e669b4..97a5f816af077 100644 --- a/system/lib/libc/musl/src/stdio/fopen.c +++ b/system/lib/libc/musl/src/stdio/fopen.c @@ -20,12 +20,18 @@ FILE *fopen(const char *restrict filename, const char *restrict mode) fd = sys_open(filename, flags, 0666); if (fd < 0) return 0; +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (flags & O_CLOEXEC) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC); +#endif f = __fdopen(fd, mode); if (f) return f; +#ifdef __EMSCRIPTEN__ + __wasi_fd_close(fd); +#else __syscall(SYS_close, fd); +#endif return 0; } diff --git a/system/lib/libc/musl/src/stdio/fprintf.c b/system/lib/libc/musl/src/stdio/fprintf.c index 948743f7c8b78..b8b779767d55d 100644 --- a/system/lib/libc/musl/src/stdio/fprintf.c +++ b/system/lib/libc/musl/src/stdio/fprintf.c @@ -1,3 +1,4 @@ +#include "stdio_impl.h" #include #include @@ -10,3 +11,24 @@ int fprintf(FILE *restrict f, const char *restrict fmt, ...) va_end(ap); return ret; } + +// XXX EMSCRIPTEN +int fiprintf(FILE *restrict f, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vfiprintf(f, fmt, ap); + va_end(ap); + return ret; +} + +int __small_fprintf(FILE *restrict f, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = __small_vfprintf(f, fmt, ap); + va_end(ap); + return ret; +} diff --git a/system/lib/libc/musl/src/stdio/freopen.c b/system/lib/libc/musl/src/stdio/freopen.c index 1641a4c5e92d5..206b5c3eeff21 100644 --- a/system/lib/libc/musl/src/stdio/freopen.c +++ b/system/lib/libc/musl/src/stdio/freopen.c @@ -20,8 +20,10 @@ FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *re fflush(f); if (!filename) { +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (fl&O_CLOEXEC) __syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC); +#endif fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC); if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0) goto fail; diff --git a/system/lib/libc/musl/src/stdio/getc.h b/system/lib/libc/musl/src/stdio/getc.h index e24f9905c1f8c..f2700b41d2223 100644 --- a/system/lib/libc/musl/src/stdio/getc.h +++ b/system/lib/libc/musl/src/stdio/getc.h @@ -16,7 +16,7 @@ static int locking_getc(FILE *f) static inline int do_getc(FILE *f) { int l = f->lock; - if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid) + if (l < 0 || l && (l & ~MAYBE_WAITERS) == CURRENT_THREAD_ID) return getc_unlocked(f); return locking_getc(f); } diff --git a/system/lib/libc/musl/src/stdio/printf.c b/system/lib/libc/musl/src/stdio/printf.c index cebfe404fb97d..c1722dea59086 100644 --- a/system/lib/libc/musl/src/stdio/printf.c +++ b/system/lib/libc/musl/src/stdio/printf.c @@ -1,3 +1,4 @@ +#include "stdio_impl.h" #include #include @@ -10,3 +11,25 @@ int printf(const char *restrict fmt, ...) va_end(ap); return ret; } + +// XXX EMSCRIPTEN +int iprintf(const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vfiprintf(stdout, fmt, ap); + va_end(ap); + return ret; +} + +int __small_printf(const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = __small_vfprintf(stdout, fmt, ap); + va_end(ap); + return ret; +} + diff --git a/system/lib/libc/musl/src/stdio/putc.h b/system/lib/libc/musl/src/stdio/putc.h index 2014c4ec4af9c..a284f853f3b02 100644 --- a/system/lib/libc/musl/src/stdio/putc.h +++ b/system/lib/libc/musl/src/stdio/putc.h @@ -16,7 +16,7 @@ static int locking_putc(int c, FILE *f) static inline int do_putc(int c, FILE *f) { int l = f->lock; - if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid) + if (l < 0 || l && (l & ~MAYBE_WAITERS) == CURRENT_THREAD_ID) return putc_unlocked(c, f); return locking_putc(c, f); } diff --git a/system/lib/libc/musl/src/stdio/sprintf.c b/system/lib/libc/musl/src/stdio/sprintf.c index 9dff524c0925e..0b984e5e9951b 100644 --- a/system/lib/libc/musl/src/stdio/sprintf.c +++ b/system/lib/libc/musl/src/stdio/sprintf.c @@ -1,3 +1,4 @@ +#include "stdio_impl.h" #include #include @@ -10,3 +11,25 @@ int sprintf(char *restrict s, const char *restrict fmt, ...) va_end(ap); return ret; } + +// XXX EMSCRIPTEN +int siprintf(char *restrict s, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = vsiprintf(s, fmt, ap); + va_end(ap); + return ret; +} + +int __small_sprintf(char *restrict s, const char *restrict fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = __small_vsprintf(s, fmt, ap); + va_end(ap); + return ret; +} + diff --git a/system/lib/libc/musl/src/stdio/stdout.c b/system/lib/libc/musl/src/stdio/stdout.c index 4985a417bdda7..62cf40220a5c4 100644 --- a/system/lib/libc/musl/src/stdio/stdout.c +++ b/system/lib/libc/musl/src/stdio/stdout.c @@ -1,5 +1,19 @@ #include "stdio_impl.h" +#if __EMSCRIPTEN__ +// Emscripten doesn't support terminal seeking. +static off_t __emscripten_stdout_seek(FILE *f, off_t off, int whence) +{ + return 0; +} + +// No special work is needed to close stdout. +static int __emscripten_stdout_close(FILE *f) +{ + return 0; +} +#endif + #undef stdout static unsigned char buf[BUFSIZ+UNGET]; @@ -9,9 +23,16 @@ hidden FILE __stdout_FILE = { .fd = 1, .flags = F_PERM | F_NORD, .lbf = '\n', +#if __EMSCRIPTEN__ + // avoid stout_write which adds special terminal window size handling, which emscripten doesn't support anyhow + .write = __stdio_write, + .seek = __emscripten_stdout_seek, + .close = __emscripten_stdout_close, +#else .write = __stdout_write, .seek = __stdio_seek, .close = __stdio_close, +#endif .lock = -1, }; FILE *const stdout = &__stdout_FILE; diff --git a/system/lib/libc/musl/src/stdio/tmpfile.c b/system/lib/libc/musl/src/stdio/tmpfile.c index 2fa8803fc2312..81f8f0cdc7e7b 100644 --- a/system/lib/libc/musl/src/stdio/tmpfile.c +++ b/system/lib/libc/musl/src/stdio/tmpfile.c @@ -21,7 +21,11 @@ FILE *tmpfile(void) __syscall(SYS_unlinkat, AT_FDCWD, s, 0); #endif f = __fdopen(fd, "w+"); +#ifdef __EMSCRIPTEN__ + if (!f) __wasi_fd_close(fd); +#else if (!f) __syscall(SYS_close, fd); +#endif return f; } } diff --git a/system/lib/libc/musl/src/stdio/vfprintf.c b/system/lib/libc/musl/src/stdio/vfprintf.c index 514a44dde0a90..96779841164ce 100644 --- a/system/lib/libc/musl/src/stdio/vfprintf.c +++ b/system/lib/libc/musl/src/stdio/vfprintf.c @@ -11,6 +11,39 @@ #include #include +#ifndef EMSCRIPTEN_PRINTF_LONG_DOUBLE +// XXX EMSCRIPTEN - while wasm32 has long double = float128, we don't support +// printing at full precision by default. instead, we lower to +// 64-bit double. These macros makes our changes a little less +// invasive. +typedef double long_double; +#undef LDBL_TRUE_MIN +#define LDBL_TRUE_MIN DBL_DENORM_MIN +#undef LDBL_MIN +#define LDBL_MIN DBL_MIN +#undef LDBL_MAX +#define LDBL_MAX DBL_MAX +#undef LDBL_EPSILON +#define LDBL_EPSILON DBL_EPSILON +#undef LDBL_MANT_DIG +#define LDBL_MANT_DIG DBL_MANT_DIG +#undef LDBL_MIN_EXP +#define LDBL_MIN_EXP DBL_MIN_EXP +#undef LDBL_MAX_EXP +#define LDBL_MAX_EXP DBL_MAX_EXP +#undef LDBL_DIG +#define LDBL_DIG DBL_DIG +#undef LDBL_MIN_10_EXP +#define LDBL_MIN_10_EXP DBL_MIN_10_EXP +#undef LDBL_MAX_10_EXP +#define LDBL_MAX_10_EXP DBL_MAX_10_EXP +#undef frexpl +#define frexpl(x, exp) frexp(x, exp) +#else // EMSCRIPTEN_FULL_LONG_DOUBLE_PRINTING +// XXX EMSCRIPTEN - full long double printing support +typedef long double long_double; +#endif + /* Some useful macros */ #define MAX(a,b) ((a)>(b) ? (a) : (b)) @@ -54,7 +87,9 @@ static const unsigned char states[]['z'-'A'+1] = { S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, S('c') = INT, S('C') = UINT, S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, +#ifndef __EMSCRIPTEN__ // 'm' is a gnu extension, and strerror brings in 2.5K of strings S('m') = NOARG, +#endif S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE, }, { /* 1: l-prefixed */ @@ -102,11 +137,20 @@ static const unsigned char states[]['z'-'A'+1] = { union arg { uintmax_t i; - long double f; + long_double f; void *p; }; -static void pop_arg(union arg *arg, int type, va_list *ap) +// XXX EMSCRIPTEN - split out long double, so we don't always link in +// long double support for float printf. +typedef void (*pop_arg_long_double_t)(union arg *arg, va_list *ap); + +static void pop_arg_long_double(union arg *arg, va_list *ap) +{ + arg->f = va_arg(*ap, long double); +} + +static void pop_arg(union arg *arg, int type, va_list *ap, pop_arg_long_double_t pop_arg_long_double) { switch (type) { case PTR: arg->p = va_arg(*ap, void *); @@ -126,7 +170,7 @@ static void pop_arg(union arg *arg, int type, va_list *ap) break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t); break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *); break; case DBL: arg->f = va_arg(*ap, double); - break; case LDBL: arg->f = va_arg(*ap, long double); + break; case LDBL: pop_arg_long_double(arg, ap); } } @@ -175,10 +219,16 @@ static char *fmt_u(uintmax_t x, char *s) * depends on the float.h constants being right. If they are wrong, it * may overflow the stack. */ #if LDBL_MANT_DIG == 53 -typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; +typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long_double)]; #endif -static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) +// XXX EMSCRIPTEN - access fmt_fp indirectly, so that iprintf doesn't +// get it linked in +// also use a double argument here, as mentioned before, +// we print float128s at double precision +typedef int (*fmt_fp_t)(FILE *f, long_double y, int w, int p, int fl, int t, int ps); + +static int fmt_fp(FILE *f, long_double y, int w, int p, int fl, int t, int ps) { int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG; int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP; @@ -318,8 +368,8 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) x = *d % i; /* Are there any significant digits past j? */ if (x || d+1!=z) { - long double round = 2/LDBL_EPSILON; - long double small; + long_double round = 2/LDBL_EPSILON; + long_double small; if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1))) round += 2; if (x=0) { if (!f) nl_type[argpos]=st; else arg=nl_arg[argpos]; - } else if (f) pop_arg(&arg, st, ap); + } else if (f) pop_arg(&arg, st, ap, pop_arg_long_double); else return 0; } @@ -593,8 +645,10 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, *(a=z-(p=1))=arg.i; fl &= ~ZERO_PAD; break; +#ifndef __EMSCRIPTEN__ // 'm' is a gnu extension, and strerror brings in 2.5K of strings case 'm': if (1) a = strerror(errno); else +#endif case 's': a = arg.p ? arg.p : "(null)"; z = a + strnlen(a, p<0 ? INT_MAX : p); @@ -648,7 +702,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, if (!l10n) return 0; for (i=1; i<=NL_ARGMAX && nl_type[i]; i++) - pop_arg(nl_arg+i, nl_type[i], ap); + pop_arg(nl_arg+i, nl_type[i], ap, pop_arg_long_double); for (; i<=NL_ARGMAX && !nl_type[i]; i++); if (i<=NL_ARGMAX) goto inval; return 1; @@ -661,7 +715,9 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, return -1; } -int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) +// XXX EMSCRIPTEN: pass in fmt_fp and pop_arg as a function pointer, so iprintf/__small_printf don't +// force linking in of floating-point code. +int __vfprintf_internal(FILE *restrict f, const char *restrict fmt, va_list ap, fmt_fp_t fmt_fp, pop_arg_long_double_t pop_arg_long_double) { va_list ap2; int nl_type[NL_ARGMAX+1] = {0}; @@ -672,7 +728,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) /* the copy allows passing va_list* even if va_list is an array */ va_copy(ap2, ap); - if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) { + if (printf_core(0, fmt, &ap2, nl_arg, nl_type, fmt_fp, pop_arg_long_double) < 0) { va_end(ap2); return -1; } @@ -687,7 +743,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) f->wpos = f->wbase = f->wend = 0; } if (!f->wend && __towrite(f)) ret = -1; - else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type); + else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type, fmt_fp, pop_arg_long_double); if (saved_buf) { f->write(f, 0, 0); if (!f->wpos) ret = -1; @@ -701,3 +757,20 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) va_end(ap2); return ret; } + +int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) +{ + return __vfprintf_internal(f, fmt, ap, fmt_fp, pop_arg_long_double); +} + +// XXX EMSCRIPTEN +int vfiprintf(FILE *restrict f, const char *restrict fmt, va_list ap) +{ + return __vfprintf_internal(f, fmt, ap, NULL, NULL); +} + +// XXX EMSCRIPTEN +int __small_vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) +{ + return __vfprintf_internal(f, fmt, ap, fmt_fp, NULL); +} diff --git a/system/lib/libc/musl/src/stdio/vsnprintf.c b/system/lib/libc/musl/src/stdio/vsnprintf.c index 409b9c8583db8..4d18b50450ef6 100644 --- a/system/lib/libc/musl/src/stdio/vsnprintf.c +++ b/system/lib/libc/musl/src/stdio/vsnprintf.c @@ -48,3 +48,58 @@ int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) *c.s = 0; return vfprintf(&f, fmt, ap); } + +// XXX EMSCRIPTEN +int vsniprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) +{ + int r; + char b; + FILE f = { .lbf = EOF, .write = sn_write, .lock = -1 }; + + if (n-1 > INT_MAX-1) { + if (n) { + errno = EOVERFLOW; + return -1; + } + s = &b; + n = 1; + } + + /* Ensure pointers don't wrap if "infinite" n is passed in */ + if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; + f.buf_size = n; + f.buf = f.wpos = (void *)s; + f.wbase = f.wend = (void *)(s+n); + r = vfiprintf(&f, fmt, ap); + + /* Null-terminate, overwriting last char if dest buffer is full */ + if (n) f.wpos[-(f.wpos == f.wend)] = 0; + return r; +} + +int __small_vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) +{ + int r; + char b; + FILE f = { .lbf = EOF, .write = sn_write, .lock = -1 }; + + if (n-1 > INT_MAX-1) { + if (n) { + errno = EOVERFLOW; + return -1; + } + s = &b; + n = 1; + } + + /* Ensure pointers don't wrap if "infinite" n is passed in */ + if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; + f.buf_size = n; + f.buf = f.wpos = (void *)s; + f.wbase = f.wend = (void *)(s+n); + r = __small_vfprintf(&f, fmt, ap); + + /* Null-terminate, overwriting last char if dest buffer is full */ + if (n) f.wpos[-(f.wpos == f.wend)] = 0; + return r; +} diff --git a/system/lib/libc/musl/src/stdio/vsprintf.c b/system/lib/libc/musl/src/stdio/vsprintf.c index c57349d4d888d..c171886f6abf7 100644 --- a/system/lib/libc/musl/src/stdio/vsprintf.c +++ b/system/lib/libc/musl/src/stdio/vsprintf.c @@ -1,3 +1,4 @@ +#include "stdio_impl.h" #include #include @@ -5,3 +6,15 @@ int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) { return vsnprintf(s, INT_MAX, fmt, ap); } + +// XXX EMSCRIPTEN +int vsiprintf(char *restrict s, const char *restrict fmt, va_list ap) +{ + return vsniprintf(s, INT_MAX, fmt, ap); +} + +int __small_vsprintf(char *restrict s, const char *restrict fmt, va_list ap) +{ + return __small_vsnprintf(s, INT_MAX, fmt, ap); +} + diff --git a/system/lib/libc/musl/src/stdlib/strtol.c b/system/lib/libc/musl/src/stdlib/strtol.c index bfefea69d1c4f..29a7f1ad74965 100644 --- a/system/lib/libc/musl/src/stdlib/strtol.c +++ b/system/lib/libc/musl/src/stdlib/strtol.c @@ -5,6 +5,89 @@ #include #include +#ifdef __EMSCRIPTEN__ +#include + +// Loosely based on __intscan but simplified, and optimized for size +// - Doesn't use FILE or getc/ungetc, just operates directly on memory +// - Avoids lookup table +// - Avoids special cases loops for certain bases +// - Skips an early exit with EINVAL when char 0 is greater than base. Its not +// clear this was correct, and glibc seems not do this either. +static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim) { + int neg=0; + unsigned long long y=0; + const char* orig = s; + + if (base > 36) { + errno = EINVAL; + return 0; + } + + while (*s && isspace(*s)) { s++; }; + + // Handle sign + if (*s=='+' || *s=='-') { + neg = -(*s=='-'); + s++; + } + + int found_digit = 0; + + // Handle hex/octal prefix 0x/00 + if ((base == 0 || base == 16) && *s=='0') { + found_digit = 1; + s++; + if ((*s|32)=='x') { + s++; + base = 16; + } else if (base == 0) { + base = 8; + } + } else if (base == 0) { + base = 10; + } + + int val; + int overflow = 0; + for (y=0; ; s++) { + if ('0' <= *s && *s <= '9') val = *s -'0'; + else if ('a' <= *s && *s <= 'z') val = 10 + *s -'a'; + else if ('A' <= *s && *s <= 'Z') val = 10 + *s -'A'; + else break; + if (val>=base) break; + if (y > ULLONG_MAX/base || (base*y>ULLONG_MAX-val)) { + overflow = 1; + continue; + } + found_digit = 1; + y = y*base + val; + } + if (p) { + if (found_digit) { + *p = (char*)s; + } else { + *p = (char*)orig; + } + } + if (overflow) { + // We exit'd the above loop due to overflow + errno = ERANGE; + y = lim; + if (lim&1) neg = 0; + } + if (y>=lim) { + if (!(lim&1) && !neg) { + errno = ERANGE; + return lim-1; + } else if (y>lim) { + errno = ERANGE; + return lim; + } + } + return (y^neg)-neg; +} +#else static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim) { FILE f; @@ -17,6 +100,7 @@ static unsigned long long strtox(const char *s, char **p, int base, unsigned lon } return y; } +#endif unsigned long long strtoull(const char *restrict s, char **restrict p, int base) { diff --git a/system/lib/libc/musl/src/string/memchr.c b/system/lib/libc/musl/src/string/memchr.c index 65f0d789b2c9a..bad4e75cc3f38 100644 --- a/system/lib/libc/musl/src/string/memchr.c +++ b/system/lib/libc/musl/src/string/memchr.c @@ -12,7 +12,8 @@ void *memchr(const void *src, int c, size_t n) { const unsigned char *s = src; c = (unsigned char)c; -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--); if (n && *s != c) { typedef size_t __attribute__((__may_alias__)) word; diff --git a/system/lib/libc/musl/src/string/memcmp.c b/system/lib/libc/musl/src/string/memcmp.c index bdbce9f0f563c..c93cf8cc97330 100644 --- a/system/lib/libc/musl/src/string/memcmp.c +++ b/system/lib/libc/musl/src/string/memcmp.c @@ -1,8 +1,32 @@ +#if __EMSCRIPTEN__ +#include +#endif #include int memcmp(const void *vl, const void *vr, size_t n) { const unsigned char *l=vl, *r=vr; + +// XXX EMSCRIPTEN: add an optimized version. +#if !defined(EMSCRIPTEN_OPTIMIZE_FOR_OZ) && !__has_feature(address_sanitizer) + // If we have enough bytes, and everything is aligned, loop on words instead + // of single bytes. + if (n >= 4 && !((((uintptr_t)l) & 3) | (((uintptr_t)r) & 3))) { + while (n >= 4) { + if (*((uint32_t *)l) != *((uint32_t *)r)) { + // Go to the single-byte loop to find the specific byte. + break; + } + l += 4; + r += 4; + n -= 4; + } + } +#endif + +#if defined(EMSCRIPTEN_OPTIMIZE_FOR_OZ) +#pragma clang loop unroll(disable) +#endif for (; n && *l == *r; n--, l++, r++); return n ? *l-*r : 0; } diff --git a/system/lib/libc/musl/src/string/stpcpy.c b/system/lib/libc/musl/src/string/stpcpy.c index 4db46a9e50b2f..b3685bf5ac2dc 100644 --- a/system/lib/libc/musl/src/string/stpcpy.c +++ b/system/lib/libc/musl/src/string/stpcpy.c @@ -1,6 +1,7 @@ #include #include #include +#include "libc.h" #define ALIGN (sizeof(size_t)) #define ONES ((size_t)-1/UCHAR_MAX) @@ -9,7 +10,8 @@ char *__stpcpy(char *restrict d, const char *restrict s) { -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) typedef size_t __attribute__((__may_alias__)) word; word *wd; const word *ws; diff --git a/system/lib/libc/musl/src/string/stpncpy.c b/system/lib/libc/musl/src/string/stpncpy.c index f57fa6b71bf3d..2e3f67ef3abce 100644 --- a/system/lib/libc/musl/src/string/stpncpy.c +++ b/system/lib/libc/musl/src/string/stpncpy.c @@ -1,6 +1,7 @@ #include #include #include +#include "libc.h" #define ALIGN (sizeof(size_t)-1) #define ONES ((size_t)-1/UCHAR_MAX) @@ -9,7 +10,8 @@ char *__stpncpy(char *restrict d, const char *restrict s, size_t n) { -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) typedef size_t __attribute__((__may_alias__)) word; word *wd; const word *ws; @@ -29,4 +31,3 @@ char *__stpncpy(char *restrict d, const char *restrict s, size_t n) } weak_alias(__stpncpy, stpncpy); - diff --git a/system/lib/libc/musl/src/string/strchrnul.c b/system/lib/libc/musl/src/string/strchrnul.c index 39e2635b3064d..0ead0dffdcdf6 100644 --- a/system/lib/libc/musl/src/string/strchrnul.c +++ b/system/lib/libc/musl/src/string/strchrnul.c @@ -1,6 +1,7 @@ #include #include #include +#include "libc.h" #define ALIGN (sizeof(size_t)) #define ONES ((size_t)-1/UCHAR_MAX) @@ -12,7 +13,8 @@ char *__strchrnul(const char *s, int c) c = (unsigned char)c; if (!c) return (char *)s + strlen(s); -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) typedef size_t __attribute__((__may_alias__)) word; const word *w; for (; (uintptr_t)s % ALIGN; s++) diff --git a/system/lib/libc/musl/src/string/strlen.c b/system/lib/libc/musl/src/string/strlen.c index 309990f029f0c..aab0719519f6e 100644 --- a/system/lib/libc/musl/src/string/strlen.c +++ b/system/lib/libc/musl/src/string/strlen.c @@ -10,7 +10,8 @@ size_t strlen(const char *s) { const char *a = s; -#ifdef __GNUC__ +/* XXX EMSCRIPTEN: add __has_feature check */ +#if defined(__GNUC__) && !__has_feature(address_sanitizer) typedef size_t __attribute__((__may_alias__)) word; const word *w; for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a; diff --git a/system/lib/libc/musl/src/temp/__randname.c b/system/lib/libc/musl/src/temp/__randname.c index e9b970f1f6360..62152de05b5ed 100644 --- a/system/lib/libc/musl/src/temp/__randname.c +++ b/system/lib/libc/musl/src/temp/__randname.c @@ -12,6 +12,11 @@ char *__randname(char *template) __clock_gettime(CLOCK_REALTIME, &ts); r = ts.tv_sec + ts.tv_nsec + __pthread_self()->tid * 65537UL; + + /* XXX EMSCRIPTEN: avoid repeating the same result when __clock_gettime does not change between calls. */ + static unsigned int counter = 0; + r += counter++; + for (i=0; i<6; i++, r>>=5) template[i] = 'A'+(r&15)+(r&16)*2; diff --git a/system/lib/libc/musl/src/thread/__timedwait.c b/system/lib/libc/musl/src/thread/__timedwait.c index 666093be98516..9e3ccc9849257 100644 --- a/system/lib/libc/musl/src/thread/__timedwait.c +++ b/system/lib/libc/musl/src/thread/__timedwait.c @@ -1,10 +1,17 @@ #include #include #include +#ifdef __EMSCRIPTEN__ +#include +#include +#include +#else #include "futex.h" +#endif #include "syscall.h" #include "pthread_impl.h" +#ifndef __EMSCRIPTEN__ #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) @@ -25,6 +32,7 @@ static int __futex4_cp(volatile void *addr, int op, int val, const struct timesp if (r != -ENOSYS) return r; return __syscall_cp(SYS_futex, addr, op & ~FUTEX_PRIVATE, val, to); } +#endif static volatile int dummy = 0; weak_alias(dummy, __eintr_valid_flag); @@ -49,7 +57,12 @@ int __timedwait_cp(volatile int *addr, int val, top = &to; } +#ifdef __EMSCRIPTEN__ + double msecs_to_sleep = top ? (top->tv_sec * 1000 + top->tv_nsec / 1000000.0) : INFINITY; + r = -emscripten_futex_wait((void*)addr, val, msecs_to_sleep); +#else r = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top); +#endif if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0; /* Mitigate bug in old kernels wrongly reporting EINTR for non- * interrupting (SA_RESTART) signal handlers. This is only practical @@ -65,7 +78,14 @@ int __timedwait(volatile int *addr, int val, { int cs, r; __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); +#ifdef __EMSCRIPTEN__ + emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_RUNNING, EM_THREAD_STATUS_WAITMUTEX); +#endif r = __timedwait_cp(addr, val, clk, at, priv); +#ifdef __EMSCRIPTEN__ + emscripten_conditional_set_current_thread_status(EM_THREAD_STATUS_WAITMUTEX, EM_THREAD_STATUS_RUNNING); +#endif __pthread_setcancelstate(cs, 0); + return r; } diff --git a/system/lib/libc/musl/src/thread/__wait.c b/system/lib/libc/musl/src/thread/__wait.c index dc33c1a30992e..66a140bd69401 100644 --- a/system/lib/libc/musl/src/thread/__wait.c +++ b/system/lib/libc/musl/src/thread/__wait.c @@ -1,3 +1,8 @@ +#ifdef __EMSCRIPTEN__ +#include +#include +#endif + #include "pthread_impl.h" void __wait(volatile int *addr, volatile int *waiters, int val, int priv) @@ -10,8 +15,12 @@ void __wait(volatile int *addr, volatile int *waiters, int val, int priv) } if (waiters) a_inc(waiters); while (*addr==val) { +#ifdef __EMSCRIPTEN__ + emscripten_futex_wait((void*)addr, val, INFINITY); +#else __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); +#endif } if (waiters) a_dec(waiters); } diff --git a/system/lib/libc/musl/src/thread/pthread_atfork.c b/system/lib/libc/musl/src/thread/pthread_atfork.c index 26d325438cec6..f1b40eb57ddc0 100644 --- a/system/lib/libc/musl/src/thread/pthread_atfork.c +++ b/system/lib/libc/musl/src/thread/pthread_atfork.c @@ -3,6 +3,7 @@ #include "libc.h" #include "lock.h" +#ifndef __EMSCRIPTEN__ // XXX Emscripten fork() is not supported: pthread_atfork is a no-op #define malloc __libc_malloc #define calloc undef #define realloc undef @@ -36,9 +37,13 @@ void __fork_handler(int who) UNLOCK(lock); } } +#endif int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) { +#ifdef __EMSCRIPTEN__ // XXX Emscripten fork() is not supported: pthread_atfork is a no-op + return 0; +#else struct atfork_funcs *new = malloc(sizeof *new); if (!new) return ENOMEM; @@ -52,4 +57,5 @@ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(vo funcs = new; UNLOCK(lock); return 0; +#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_attr_get.c b/system/lib/libc/musl/src/thread/pthread_attr_get.c index f12ff442548dd..73e30a5f01214 100644 --- a/system/lib/libc/musl/src/thread/pthread_attr_get.c +++ b/system/lib/libc/musl/src/thread/pthread_attr_get.c @@ -37,8 +37,12 @@ int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope) int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size) { - if (!a->_a_stackaddr) - return EINVAL; +/// XXX musl is not standard-conforming? It should not report EINVAL if _a_stackaddr is zero, and it should +/// report EINVAL if a is null: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getstack.html + if (!a) return EINVAL; +// if (!a->_a_stackaddr) +// return EINVAL; + *size = a->_a_stacksize; *addr = (void *)(a->_a_stackaddr - *size); return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_barrier_wait.c b/system/lib/libc/musl/src/thread/pthread_barrier_wait.c index cc2a8bbf58a9c..0d73d7fd33267 100644 --- a/system/lib/libc/musl/src/thread/pthread_barrier_wait.c +++ b/system/lib/libc/musl/src/thread/pthread_barrier_wait.c @@ -1,3 +1,7 @@ +#ifdef __EMSCRIPTEN__ +#include +#endif + #include "pthread_impl.h" static int pshared_barrier_wait(pthread_barrier_t *b) @@ -83,9 +87,14 @@ int pthread_barrier_wait(pthread_barrier_t *b) while (spins-- && !inst->finished) a_spin(); a_inc(&inst->finished); - while (inst->finished == 1) + while (inst->finished == 1) { +#ifdef __EMSCRIPTEN__ + emscripten_futex_wait(&inst->finished, 1, INFINITY); +#else __syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS || __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0); +#endif + } return PTHREAD_BARRIER_SERIAL_THREAD; } diff --git a/system/lib/libc/musl/src/thread/pthread_cancel.c b/system/lib/libc/musl/src/thread/pthread_cancel.c index 139a6fc84e81d..953c5a08f7e43 100644 --- a/system/lib/libc/musl/src/thread/pthread_cancel.c +++ b/system/lib/libc/musl/src/thread/pthread_cancel.c @@ -8,12 +8,13 @@ hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c(); long __cancel() { pthread_t self = __pthread_self(); - if (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync) + if (self->canceldisable == PTHREAD_CANCEL_ENABLE) pthread_exit(PTHREAD_CANCELED); self->canceldisable = PTHREAD_CANCEL_DISABLE; return -ECANCELED; } +#ifndef __EMSCRIPTEN__ long __syscall_cp_asm(volatile void *, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t); @@ -71,6 +72,7 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) __syscall(SYS_tkill, self->tid, SIGCANCEL); } +#endif void __testcancel() { @@ -79,6 +81,7 @@ void __testcancel() __cancel(); } +#ifndef __EMSCRIPTEN__ static void init_cancellation() { struct sigaction sa = { @@ -88,19 +91,30 @@ static void init_cancellation() memset(&sa.sa_mask, -1, _NSIG/8); __libc_sigaction(SIGCANCEL, &sa, 0); } +#endif int pthread_cancel(pthread_t t) { +#ifndef __EMSCRIPTEN__ static int init; if (!init) { init_cancellation(); init = 1; } +#endif a_store(&t->cancel, 1); if (t == pthread_self()) { if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync) pthread_exit(PTHREAD_CANCELED); return 0; } +#ifdef __EMSCRIPTEN__ + // Wake the target thread in case it is in emscripten_futex_wait. Normally, + // this is only required when the target is the main runtime thread and there + // is an event added to its system queue. + // However, all threads need to be interrupted like this in the case they are + // cancelled. + _emscripten_thread_notify(t); +#endif return pthread_kill(t, SIGCANCEL); } diff --git a/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c b/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c index 6b761455c47f0..edd5a571a4585 100644 --- a/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c +++ b/system/lib/libc/musl/src/thread/pthread_cond_timedwait.c @@ -48,9 +48,19 @@ static inline void unlock(volatile int *l) static inline void unlock_requeue(volatile int *l, volatile int *r, int w) { a_store(l, 0); +#ifdef __EMSCRIPTEN__ + // Here the intent is to wake one waiter, and requeue all other waiters from waiting on address 'l' + // to wait on address 'r' instead. This is not possible at the moment with SharedArrayBuffer Atomics, + // as it does not have a "wake X waiters and requeue the rest" primitive. However this kind of + // primitive is strictly not needed, since it is more like an optimization to avoid spuriously waking + // all waiters, just to make them wait on another location immediately afterwards. Here we do exactly + // that: wake every waiter. + emscripten_futex_wake(l, INT_MAX); +#else if (w) __wake(l, 1, 1); else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r); +#endif } enum { @@ -65,6 +75,13 @@ int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restri int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp; volatile int *fut; +#ifdef __EMSCRIPTEN__ + // TODO: Optimize this away in MINIMAL_RUNTIME. + if (emscripten_is_main_browser_thread()) { + emscripten_check_blocking_allowed(); + } +#endif + if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid) return EPERM; diff --git a/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c b/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c index 51453e0480a82..809cc68d20a51 100644 --- a/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c +++ b/system/lib/libc/musl/src/thread/pthread_condattr_setpshared.c @@ -3,6 +3,9 @@ int pthread_condattr_setpshared(pthread_condattr_t *a, int pshared) { if (pshared > 1U) return EINVAL; +#ifdef __EMSCRIPTEN__ + if (pshared) return ENOTSUP; +#endif a->__attr &= 0x7fffffff; a->__attr |= (unsigned)pshared<<31; return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_detach.c b/system/lib/libc/musl/src/thread/pthread_detach.c index d73a500e79adc..c25882cca4ac1 100644 --- a/system/lib/libc/musl/src/thread/pthread_detach.c +++ b/system/lib/libc/musl/src/thread/pthread_detach.c @@ -3,9 +3,25 @@ static int __pthread_detach(pthread_t t) { +#ifdef __EMSCRIPTEN__ + // XXX EMSCRIPTEN: Add check for invalid (already joined) thread. Again + // for the benefit of the conformance tests. + if (!_emscripten_thread_is_valid(t)) + return ESRCH; +#endif /* If the cas fails, detach state is either already-detached * or exiting/exited, and pthread_join will trap or cleanup. */ +#ifdef __EMSCRIPTEN__ + int old_state = a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED); + if (old_state != DT_JOINABLE) { + // Even though the man page says this is undefined behaviour to attempt to + // detach an already-detached thread we have several tests in the posixtest + // suite that depend on this (pthread_join.c) + if (old_state == DT_DETACHED) + return EINVAL; +#else if (a_cas(&t->detach_state, DT_JOINABLE, DT_DETACHED) != DT_JOINABLE) { +#endif int cs; __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); __pthread_join(t, 0); @@ -16,3 +32,5 @@ static int __pthread_detach(pthread_t t) weak_alias(__pthread_detach, pthread_detach); weak_alias(__pthread_detach, thrd_detach); +// XXX EMSCRIPTEN: add extra alias for asan. +weak_alias(__pthread_detach, emscripten_builtin_pthread_detach); diff --git a/system/lib/libc/musl/src/thread/pthread_getattr_np.c b/system/lib/libc/musl/src/thread/pthread_getattr_np.c index 2881831f8c2fa..5f5246133bc32 100644 --- a/system/lib/libc/musl/src/thread/pthread_getattr_np.c +++ b/system/lib/libc/musl/src/thread/pthread_getattr_np.c @@ -8,6 +8,10 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a) *a = (pthread_attr_t){0}; a->_a_detach = t->detach_state>=DT_DETACHED; a->_a_guardsize = t->guard_size; +#ifdef __EMSCRIPTEN__ + a->_a_stackaddr = (uintptr_t)t->stack; + a->_a_stacksize = t->stack_size; +#else if (t->stack) { a->_a_stackaddr = (uintptr_t)t->stack; a->_a_stacksize = t->stack_size; @@ -20,5 +24,6 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a) l += PAGE_SIZE; a->_a_stacksize = l; } +#endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_getconcurrency.c b/system/lib/libc/musl/src/thread/pthread_getconcurrency.c index 269429a8abca8..4ab5f1b94aeee 100644 --- a/system/lib/libc/musl/src/thread/pthread_getconcurrency.c +++ b/system/lib/libc/musl/src/thread/pthread_getconcurrency.c @@ -1,5 +1,7 @@ #include +// XXX Emscripten marked as obsolescent in pthreads specification: +// http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_getconcurrency.html int pthread_getconcurrency() { return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c b/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c index 9df14fb689524..62355f43ef47d 100644 --- a/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c +++ b/system/lib/libc/musl/src/thread/pthread_getcpuclockid.c @@ -2,6 +2,11 @@ int pthread_getcpuclockid(pthread_t t, clockid_t *clockid) { +#ifdef __EMSCRIPTEN__ // XXX Emscipten per-thread CPU time clocks are not supported + // pthread API recommends returning this error when "Per-thread CPU time clocks are not supported by the system." + return ENOENT; +#else *clockid = (-t->tid-1)*8U + 6; return 0; +#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_getschedparam.c b/system/lib/libc/musl/src/thread/pthread_getschedparam.c index c098befb1b7f0..d5931b7b64e5c 100644 --- a/system/lib/libc/musl/src/thread/pthread_getschedparam.c +++ b/system/lib/libc/musl/src/thread/pthread_getschedparam.c @@ -3,6 +3,10 @@ int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param) { +#ifdef __EMSCRIPTEN__ // XXX Emscripten web or Node workers doesn't support prioritizing threads + // no-op + return 0; +#else int r; sigset_t set; __block_app_sigs(&set); @@ -18,4 +22,5 @@ int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param UNLOCK(t->killlock); __restore_sigs(&set); return r; +#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_join.c b/system/lib/libc/musl/src/thread/pthread_join.c index 17dae85d70861..a5d539b651754 100644 --- a/system/lib/libc/musl/src/thread/pthread_join.c +++ b/system/lib/libc/musl/src/thread/pthread_join.c @@ -9,32 +9,69 @@ weak_alias(dummy1, __tl_sync); static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at) { +#ifdef __EMSCRIPTEN__ + // Attempt to join a thread which does not point to a valid thread, or + // does not exist anymore. + if (!_emscripten_thread_is_valid(t)) return ESRCH; + // Thread is attempting to join to itself. Already detached threads are + // handled below by returning EINVAL instead. + // TODO: The detached check here is just to satisfy the + // `other.test_{proxy,main}_pthread_join_detach` tests. + if (t->detach_state != DT_DETACHED && __pthread_self() == t) return EDEADLK; +#endif int state, cs, r = 0; __pthread_testcancel(); __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); if (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0); while ((state = t->detach_state) && r != ETIMEDOUT && r != EINVAL) { +#ifdef __EMSCRIPTEN__ + // The thread is (already) detached and therefore not joinable. + // This also handle cases where the thread becomes detached + // *during* the join. + if (state >= DT_DETACHED) { + // Even though the man page says this is undefined behaviour we have + // several tests in the posixtest suite that depend on this. + r = EINVAL; + break; + } +#else if (state >= DT_DETACHED) a_crash(); +#endif r = __timedwait_cp(&t->detach_state, state, CLOCK_REALTIME, at, 1); } __pthread_setcancelstate(cs, 0); if (r == ETIMEDOUT || r == EINVAL) return r; __tl_sync(t); if (res) *res = t->result; +#ifdef __EMSCRIPTEN__ + // Thread was exited during this call, be sure to clean it up. + if (state == DT_EXITED) _emscripten_thread_cleanup(t); +#else // XXX Emscripten map_base unused if (t->map_base) __munmap(t->map_base, t->map_size); +#endif return 0; } int __pthread_join(pthread_t t, void **res) { +#ifdef __EMSCRIPTEN__ // XXX Emscripten check whether blocking is allowed. + emscripten_check_blocking_allowed(); +#endif return __pthread_timedjoin_np(t, res, 0); } static int __pthread_tryjoin_np(pthread_t t, void **res) { +#ifdef __EMSCRIPTEN__ // XXX Emscripten call __pthread_timedjoin_np directly to avoid additional check + return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_timedjoin_np(t, res, 0); +#else return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_join(t, res); +#endif } weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np); weak_alias(__pthread_timedjoin_np, pthread_timedjoin_np); weak_alias(__pthread_join, pthread_join); +#ifdef __EMSCRIPTEN__ // XXX Emscripten add an extra alias for LSan +weak_alias(__pthread_join, emscripten_builtin_pthread_join); +#endif diff --git a/system/lib/libc/musl/src/thread/pthread_key_create.c b/system/lib/libc/musl/src/thread/pthread_key_create.c index 39770c7a3c829..f45553919647a 100644 --- a/system/lib/libc/musl/src/thread/pthread_key_create.c +++ b/system/lib/libc/musl/src/thread/pthread_key_create.c @@ -1,6 +1,10 @@ #include "pthread_impl.h" #include "fork_impl.h" +#ifdef __EMSCRIPTEN__ +#include +#endif + volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX; void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 }; diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_lock.c b/system/lib/libc/musl/src/thread/pthread_mutex_lock.c index 638d4b8697d84..02269d366c858 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_lock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_lock.c @@ -2,9 +2,12 @@ int __pthread_mutex_lock(pthread_mutex_t *m) { +#if !defined(__EMSCRIPTEN__) || defined(NDEBUG) + /* XXX EMSCRIPTEN always take the slow path in debug builds so we can trap rather than deadlock */ if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY)) return 0; +#endif return __pthread_mutex_timedlock(m, 0); } diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c index 9279fc54308ad..232c9b321a8e2 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c @@ -1,5 +1,10 @@ #include "pthread_impl.h" +#ifdef __EMSCRIPTEN__ +#include +#endif + +#ifndef __EMSCRIPTEN__ #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) @@ -52,12 +57,16 @@ static int pthread_mutex_timedlock_pi(pthread_mutex_t *restrict m, const struct while (e != ETIMEDOUT); return e; } +#endif int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at) { +#if !defined(__EMSCRIPTEN__) || defined(NDEBUG) + /* XXX EMSCRIPTEN always take the slow path in debug builds so we can trap rather than deadlock */ if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY)) return 0; +#endif int type = m->_m_type; int r, t, priv = (type & 128) ^ 128; @@ -65,7 +74,9 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec r = __pthread_mutex_trylock(m); if (r != EBUSY) return r; +#ifndef __EMSCRIPTEN__ if (type&8) return pthread_mutex_timedlock_pi(m, at); +#endif int spins = 100; while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); @@ -78,6 +89,11 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec if ((type&3) == PTHREAD_MUTEX_ERRORCHECK && own == __pthread_self()->tid) return EDEADLK; +#if defined(__EMSCRIPTEN__) && !defined(NDEBUG) + // Extra check for deadlock in debug builds, but only if we would block + // forever (at == NULL). + assert(at || own != __pthread_self()->tid && "pthread mutex deadlock detected"); +#endif a_inc(&m->_m_waiters); t = r | 0x80000000; diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c b/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c index a24e7c58ac390..9a6719cf63b3a 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_trylock.c @@ -6,6 +6,7 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) int type = m->_m_type; pthread_t self = __pthread_self(); int tid = self->tid; + volatile void *next; old = m->_m_lock; own = old & 0x3fffffff; @@ -27,7 +28,9 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) if (type & 128) { if (!self->robust_list.off) { self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next; +#ifndef __EMSCRIPTEN__ // XXX Emscripten does not have a concept of multiple processes or kernel space, so robust mutex lists don't need to register to kernel. __syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long)); +#endif } if (m->_m_waiters) tid |= 0x80000000; self->robust_list.pending = &m->_m_next; @@ -41,14 +44,22 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) } success: +#ifndef __EMSCRIPTEN__ if ((type&8) && m->_m_waiters) { int priv = (type & 128) ^ 128; __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); self->robust_list.pending = 0; return (type&4) ? ENOTRECOVERABLE : EBUSY; } +#endif - volatile void *next = self->robust_list.head; +#if defined(__EMSCRIPTEN__) && !defined(NDEBUG) + // Under emscripten we can get here for normal mutexes too, but only in debug + // builds (where we track ownership purely for debug purposes). + if ((type&15) == PTHREAD_MUTEX_NORMAL) return 0; +#endif + + next = self->robust_list.head; m->_m_next = next; m->_m_prev = &self->robust_list.head; if (next != &self->robust_list.head) *(volatile void *volatile *) @@ -66,8 +77,11 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) int __pthread_mutex_trylock(pthread_mutex_t *m) { +#if !defined(__EMSCRIPTEN__) || defined(NDEBUG) + /* XXX EMSCRIPTEN always take the slow path in debug builds so we can trap rather than deadlock */ if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL) return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY; +#endif return __pthread_mutex_trylock_owner(m); } diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c index b66423e6c34f7..af13bcfa12012 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_unlock.c @@ -30,6 +30,9 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) if (next != &self->robust_list.head) *(volatile void *volatile *) ((char *)next - sizeof(void *)) = prev; } +#ifdef __EMSCRIPTEN__ + cont = a_swap(&m->_m_lock, new); +#else if (type&8) { if (old<0 || a_cas(&m->_m_lock, old, new)!=old) { if (new) a_store(&m->_m_waiters, -1); @@ -40,6 +43,7 @@ int __pthread_mutex_unlock(pthread_mutex_t *m) } else { cont = a_swap(&m->_m_lock, new); } +#endif if (type != PTHREAD_MUTEX_NORMAL && !priv) { self->robust_list.pending = 0; __vm_unlock(); diff --git a/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c b/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c index 8b80c1ce9b14c..bda16ebd5ba21 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c +++ b/system/lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c @@ -11,6 +11,7 @@ int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol) a->__attr &= ~8; return 0; case PTHREAD_PRIO_INHERIT: +#ifndef __EMSCRIPTEN__ r = check_pi_result; if (r < 0) { volatile int lk = 0; @@ -20,6 +21,7 @@ int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol) if (r) return r; a->__attr |= 8; return 0; +#endif case PTHREAD_PRIO_PROTECT: return ENOTSUP; default: diff --git a/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c b/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c index 100f6ff203f1b..e2f0d3cb859e8 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c +++ b/system/lib/libc/musl/src/thread/pthread_mutexattr_setpshared.c @@ -3,6 +3,9 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int pshared) { if (pshared > 1U) return EINVAL; +#ifdef __EMSCRIPTEN__ + if (pshared) return ENOTSUP; +#endif a->__attr &= ~128U; a->__attr |= pshared<<7; return 0; diff --git a/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c b/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c index 30a9ac3bea559..7e181e2c0639e 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c +++ b/system/lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c @@ -7,6 +7,7 @@ int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust) { if (robust > 1U) return EINVAL; if (robust) { +#ifndef __EMSCRIPTEN__ int r = check_robust_result; if (r < 0) { void *p; @@ -15,6 +16,7 @@ int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust) a_store(&check_robust_result, r); } if (r) return r; +#endif a->__attr |= 4; return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c index d77706e6bc208..b147cb92ea9f5 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_timedwrlock.c @@ -2,11 +2,16 @@ int __pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at) { +#ifdef __EMSCRIPTEN__ + /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. + /// If attempting to lock the write lock that we already own, error out. + if (rw->_rw_wr_owner == __pthread_self()->tid) return EDEADLK; +#endif int r, t; - + r = pthread_rwlock_trywrlock(rw); if (r != EBUSY) return r; - + int spins = 100; while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin(); @@ -19,6 +24,11 @@ int __pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct tim a_dec(&rw->_rw_waiters); if (r && r != EINTR) return r; } +#ifdef __EMSCRIPTEN__ + /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. + /// Mark this thread as the owner of this write lock. + rw->_rw_wr_owner = __pthread_self()->tid; +#endif return r; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c index 64d9d3121a709..e275bdaf1a1f1 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_trywrlock.c @@ -3,6 +3,11 @@ int __pthread_rwlock_trywrlock(pthread_rwlock_t *rw) { if (a_cas(&rw->_rw_lock, 0, 0x7fffffff)) return EBUSY; +#ifdef __EMSCRIPTEN__ + /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. + /// Mark this thread to own the write lock, to ignore multiple attempts to lock. + rw->_rw_wr_owner = __pthread_self()->tid; +#endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c b/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c index 9ae27ad2b3a76..7a55a085a0288 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlock_unlock.c @@ -4,6 +4,12 @@ int __pthread_rwlock_unlock(pthread_rwlock_t *rw) { int val, cnt, waiters, new, priv = rw->_rw_shared^128; +#ifdef __EMSCRIPTEN__ + /// XXX Emscripten: The spec allows detecting when multiple write locks would deadlock, which we do here to avoid hangs. + /// Mark this thread to not own the write lock anymore. + if (rw->_rw_wr_owner == __pthread_self()->tid) rw->_rw_wr_owner = 0; +#endif + do { val = rw->_rw_lock; cnt = val & 0x7fffffff; diff --git a/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c b/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c index e7061973d6d6b..33f9466a60ddb 100644 --- a/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c +++ b/system/lib/libc/musl/src/thread/pthread_rwlockattr_setpshared.c @@ -3,6 +3,9 @@ int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int pshared) { if (pshared > 1U) return EINVAL; +#ifdef __EMSCRIPTEN__ + if (pshared) return ENOTSUP; +#endif a->__attr[0] = pshared; return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_setconcurrency.c b/system/lib/libc/musl/src/thread/pthread_setconcurrency.c index 091abf98c86f3..deadf26ba9433 100644 --- a/system/lib/libc/musl/src/thread/pthread_setconcurrency.c +++ b/system/lib/libc/musl/src/thread/pthread_setconcurrency.c @@ -3,7 +3,9 @@ int pthread_setconcurrency(int val) { +#ifndef __EMSCRIPTEN__ // XXX Emscripten marked as obsolescent in pthreads specification if (val < 0) return EINVAL; if (val > 0) return EAGAIN; +#endif return 0; } diff --git a/system/lib/libc/musl/src/thread/pthread_setschedparam.c b/system/lib/libc/musl/src/thread/pthread_setschedparam.c index 76d4d45a3cdae..396aff5a33be0 100644 --- a/system/lib/libc/musl/src/thread/pthread_setschedparam.c +++ b/system/lib/libc/musl/src/thread/pthread_setschedparam.c @@ -3,6 +3,10 @@ int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param) { +#ifdef __EMSCRIPTEN__ // XXX Emscripten web or Node workers doesn't support prioritizing threads + // no-op + return 0; +#else int r; sigset_t set; __block_app_sigs(&set); @@ -11,4 +15,5 @@ int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *par UNLOCK(t->killlock); __restore_sigs(&set); return r; +#endif } diff --git a/system/lib/libc/musl/src/thread/pthread_setschedprio.c b/system/lib/libc/musl/src/thread/pthread_setschedprio.c index fc2e13ddb3dbb..b8d53698683a7 100644 --- a/system/lib/libc/musl/src/thread/pthread_setschedprio.c +++ b/system/lib/libc/musl/src/thread/pthread_setschedprio.c @@ -3,6 +3,10 @@ int pthread_setschedprio(pthread_t t, int prio) { +#ifdef __EMSCRIPTEN__ // XXX Emscripten web or Node workers doesn't support prioritizing threads + // no-op + return 0; +#else int r; sigset_t set; __block_app_sigs(&set); @@ -11,4 +15,5 @@ int pthread_setschedprio(pthread_t t, int prio) UNLOCK(t->killlock); __restore_sigs(&set); return r; +#endif } diff --git a/system/lib/libc/musl/src/thread/sem_init.c b/system/lib/libc/musl/src/thread/sem_init.c index 55092434386f8..f9b851778f2c8 100644 --- a/system/lib/libc/musl/src/thread/sem_init.c +++ b/system/lib/libc/musl/src/thread/sem_init.c @@ -8,6 +8,9 @@ int sem_init(sem_t *sem, int pshared, unsigned value) errno = EINVAL; return -1; } +#ifdef __EMSCRIPTEN__ + if (pshared) return ENOTSUP; +#endif sem->__val[0] = value; sem->__val[1] = 0; sem->__val[2] = pshared ? 0 : 128; diff --git a/system/lib/libc/musl/src/thread/sem_timedwait.c b/system/lib/libc/musl/src/thread/sem_timedwait.c index aa67376c2dcd8..757795a9589dd 100644 --- a/system/lib/libc/musl/src/thread/sem_timedwait.c +++ b/system/lib/libc/musl/src/thread/sem_timedwait.c @@ -25,6 +25,9 @@ int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at) r = __timedwait_cp(sem->__val, 0x80000000, CLOCK_REALTIME, at, priv); pthread_cleanup_pop(1); if (r) { +#ifdef __EMSCRIPTEN__ + if (r == ECANCELED) r = EINTR; +#endif errno = r; return -1; } diff --git a/system/lib/libc/musl/src/thread/thrd_create.c b/system/lib/libc/musl/src/thread/thrd_create.c index 76a683dbf87e7..ca4efb661973b 100644 --- a/system/lib/libc/musl/src/thread/thrd_create.c +++ b/system/lib/libc/musl/src/thread/thrd_create.c @@ -1,6 +1,15 @@ #include "pthread_impl.h" #include +#ifdef __EMSCRIPTEN__ +// Fix for lsan. Since lsan wraps calls to the public `pthread_create` function +// if we call the internal __pthread_create function here to don't the wrapping +// See pthread_create wrapper in compiler-rt/lib/lsan/lsan_interceptors.cpp. +#define __pthread_create pthread_create +#else +int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict); +#endif + int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg); diff --git a/system/lib/libc/musl/src/thread/thrd_join.c b/system/lib/libc/musl/src/thread/thrd_join.c index 0d5fd302d1810..abcdbc1aaeac2 100644 --- a/system/lib/libc/musl/src/thread/thrd_join.c +++ b/system/lib/libc/musl/src/thread/thrd_join.c @@ -5,7 +5,11 @@ int thrd_join(thrd_t t, int *res) { void *pthread_res; - __pthread_join(t, &pthread_res); + int rtn = __pthread_join(t, &pthread_res); + // XXX Emscripten added handling of error case + if (rtn) { + return thrd_error; + } if (res) *res = (int)(intptr_t)pthread_res; return thrd_success; } diff --git a/system/lib/libc/musl/src/thread/thrd_yield.c b/system/lib/libc/musl/src/thread/thrd_yield.c index f7ad13219ce0d..d30d8843ac145 100644 --- a/system/lib/libc/musl/src/thread/thrd_yield.c +++ b/system/lib/libc/musl/src/thread/thrd_yield.c @@ -3,5 +3,7 @@ void thrd_yield() { +#ifndef __EMSCRIPTEN__ __syscall(SYS_sched_yield); +#endif } diff --git a/system/lib/libc/musl/src/time/__map_file.c b/system/lib/libc/musl/src/time/__map_file.c index c2b29fe81b905..f4520b124c0b3 100644 --- a/system/lib/libc/musl/src/time/__map_file.c +++ b/system/lib/libc/musl/src/time/__map_file.c @@ -13,6 +13,10 @@ const char unsigned *__map_file(const char *pathname, size_t *size) map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); *size = st.st_size; } +#ifdef __EMSCRIPTEN__ + __wasi_fd_close(fd); +#else __syscall(SYS_close, fd); +#endif return map == MAP_FAILED ? 0 : map; } diff --git a/system/lib/libc/musl/src/time/__tz.c b/system/lib/libc/musl/src/time/__tz.c index 54ed4cf6a783d..7da45f88ca43d 100644 --- a/system/lib/libc/musl/src/time/__tz.c +++ b/system/lib/libc/musl/src/time/__tz.c @@ -9,14 +9,19 @@ #include "lock.h" #include "fork_impl.h" +#if defined(__EMSCRIPTEN__) && !defined(EMSCRIPTEN_STANDALONE_WASM) +#define USE_EXTERNAL_ZONEINFO +#include "emscripten_internal.h" +#endif + #define malloc __libc_malloc #define calloc undef #define realloc undef #define free undef -long __timezone = 0; -int __daylight = 0; -char *__tzname[2] = { 0, 0 }; +weak long __timezone = 0; +weak int __daylight = 0; +weak char *__tzname[2] = { 0, 0 }; weak_alias(__timezone, timezone); weak_alias(__daylight, daylight); @@ -28,16 +33,21 @@ static char dst_name[TZNAME_MAX+1]; static int dst_off; static int r0[5], r1[5]; +#ifndef USE_EXTERNAL_ZONEINFO static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end; static size_t map_size; +#endif static char old_tz_buf[32]; static char *old_tz = old_tz_buf; static size_t old_tz_size = sizeof old_tz_buf; static volatile int lock[1]; +#ifndef __EMSCRIPTEN__ volatile int *const __timezone_lockptr = lock; +#endif +#ifndef USE_EXTERNAL_ZONEINFO static int getint(const char **p) { unsigned x; @@ -121,9 +131,17 @@ static size_t zi_dotprod(const unsigned char *z, const unsigned char *v, size_t } return y; } +#endif static void do_tzset() { +#ifdef USE_EXTERNAL_ZONEINFO + if (!__tzname[0]) { + _tzset_js(&timezone, &daylight, std_name, dst_name); + __tzname[0] = std_name; + __tzname[1] = dst_name; + } +#else char buf[NAME_MAX+25], *pathname=buf+24; const char *try, *s, *p; const unsigned char *map = 0; @@ -254,8 +272,10 @@ static void do_tzset() if (*s == ',') s++, getrule(&s, r0); if (*s == ',') s++, getrule(&s, r1); +#endif } +#ifndef USE_EXTERNAL_ZONEINFO /* Search zoneinfo rules to find the one that applies to the given time, * and determine alternate opposite-DST-status rule that may be needed. */ @@ -415,6 +435,7 @@ void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppo *zonename = __tzname[1]; UNLOCK(lock); } +#endif static void __tzset() { @@ -425,14 +446,16 @@ static void __tzset() weak_alias(__tzset, tzset); -const char *__tm_to_tzname(const struct tm *tm) +weak const char *__tm_to_tzname(const struct tm *tm) { const void *p = tm->__tm_zone; LOCK(lock); do_tzset(); +#ifndef USE_EXTERNAL_ZONEINFO if (p != __utc && p != __tzname[0] && p != __tzname[1] && (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs)) p = ""; +#endif UNLOCK(lock); return p; } diff --git a/system/lib/libc/musl/src/time/__utc.c b/system/lib/libc/musl/src/time/__utc.c index 9e8bfc58fb1c4..bf658341cd11a 100644 --- a/system/lib/libc/musl/src/time/__utc.c +++ b/system/lib/libc/musl/src/time/__utc.c @@ -1,3 +1,3 @@ #include "time_impl.h" -const char __utc[] = "UTC"; +weak const char __utc[] = "UTC"; diff --git a/system/lib/libc/musl/src/time/clock_getres.c b/system/lib/libc/musl/src/time/clock_getres.c index 81c6703761d44..b733fdc00f9d2 100644 --- a/system/lib/libc/musl/src/time/clock_getres.c +++ b/system/lib/libc/musl/src/time/clock_getres.c @@ -3,6 +3,20 @@ int clock_getres(clockid_t clk, struct timespec *ts) { +#ifdef __EMSCRIPTEN__ + // See https://github.com/bytecodealliance/wasmtime/issues/374 + if (clk > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk < 0) { + errno = EINVAL; + return -1; + } + __wasi_timestamp_t res; + __wasi_errno_t error = __wasi_clock_res_get(clk, &res); + if (error != __WASI_ERRNO_SUCCESS) { + return __wasi_syscall_ret(error); + } + *ts = __wasi_timestamp_to_timespec(res); + return 0; +#else #ifdef SYS_clock_getres_time64 /* On a 32-bit arch, use the old syscall if it exists. */ if (SYS_clock_getres != SYS_clock_getres_time64) { @@ -18,4 +32,5 @@ int clock_getres(clockid_t clk, struct timespec *ts) /* If reaching this point, it's a 64-bit arch or time64-only * 32-bit arch and we can get result directly into timespec. */ return syscall(SYS_clock_getres, clk, ts); +#endif } diff --git a/system/lib/libc/musl/src/time/clock_gettime.c b/system/lib/libc/musl/src/time/clock_gettime.c index 4d2ec22f38a00..18926de8ce8f3 100644 --- a/system/lib/libc/musl/src/time/clock_gettime.c +++ b/system/lib/libc/musl/src/time/clock_gettime.c @@ -56,6 +56,24 @@ static void *volatile vdso_func = (void *)cgt_init; #endif +#if __EMSCRIPTEN__ +_Static_assert(CLOCK_REALTIME == __WASI_CLOCKID_REALTIME, "monotonic clock must match"); +_Static_assert(CLOCK_MONOTONIC == __WASI_CLOCKID_MONOTONIC, "monotonic clock must match"); + +int __clock_gettime(clockid_t clk, struct timespec *ts) { + __wasi_timestamp_t timestamp; + // See https://github.com/bytecodealliance/wasmtime/issues/3714 + if (clk > __WASI_CLOCKID_THREAD_CPUTIME_ID || clk < 0) { + errno = EINVAL; + return -1; + } + if (__wasi_syscall_ret(__wasi_clock_time_get(clk, 1, ×tamp))) { + return -1; + } + *ts = __wasi_timestamp_to_timespec(timestamp); + return 0; +} +#else // __EMSCRIPTEN__ int __clock_gettime(clockid_t clk, struct timespec *ts) { int r; @@ -110,5 +128,6 @@ int __clock_gettime(clockid_t clk, struct timespec *ts) return __syscall_ret(r); #endif } +#endif //__EMSCRIPTEN__ weak_alias(__clock_gettime, clock_gettime); diff --git a/system/lib/libc/musl/src/time/clock_nanosleep.c b/system/lib/libc/musl/src/time/clock_nanosleep.c index e195499cc0729..7ad2aba1a0b7a 100644 --- a/system/lib/libc/musl/src/time/clock_nanosleep.c +++ b/system/lib/libc/musl/src/time/clock_nanosleep.c @@ -1,6 +1,10 @@ #include #include #include "syscall.h" +#if __EMSCRIPTEN__ +#include +#include +#endif #define IS32BIT(x) !((x)+0x80000000ULL>>32) #define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) @@ -8,6 +12,24 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) { if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL; +#if __EMSCRIPTEN__ + if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999L || req->tv_sec < 0) { + return EINVAL; + } + struct timespec sleep_for = *req; + if (flags & TIMER_ABSTIME) { + struct timespec now; + clock_gettime(clk, &now); + if (now.tv_sec > req->tv_sec || (now.tv_sec == req->tv_sec && now.tv_nsec >= req->tv_nsec)) { + // The requested time has already passed + return 0; + } + sleep_for.tv_sec = req->tv_sec - now.tv_sec; + sleep_for.tv_nsec = req->tv_nsec - now.tv_nsec; + } + emscripten_thread_sleep(sleep_for.tv_sec * 1000.0 + sleep_for.tv_nsec / 1e6); + return 0; +#else #ifdef SYS_clock_nanosleep_time64 time_t s = req->tv_sec; long ns = req->tv_nsec; @@ -33,6 +55,7 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, stru return -__syscall_cp(SYS_nanosleep, req, rem); return -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem); #endif +#endif } weak_alias(__clock_nanosleep, clock_nanosleep); diff --git a/system/lib/libc/musl/src/time/clock_settime.c b/system/lib/libc/musl/src/time/clock_settime.c index 1004ed1528462..ed0182fff664c 100644 --- a/system/lib/libc/musl/src/time/clock_settime.c +++ b/system/lib/libc/musl/src/time/clock_settime.c @@ -1,11 +1,19 @@ #include #include #include "syscall.h" +#ifdef __EMSCRIPTEN__ +#include +#endif #define IS32BIT(x) !((x)+0x80000000ULL>>32) int clock_settime(clockid_t clk, const struct timespec *ts) { +#ifdef __EMSCRIPTEN__ + // JS and wasm VMs do not allow setting the time. + errno = EPERM; + return -1; +#else #ifdef SYS_clock_settime64 time_t s = ts->tv_sec; long ns = ts->tv_nsec; @@ -21,4 +29,5 @@ int clock_settime(clockid_t clk, const struct timespec *ts) #else return syscall(SYS_clock_settime, clk, ts); #endif +#endif } diff --git a/system/lib/libc/musl/src/time/localtime_r.c b/system/lib/libc/musl/src/time/localtime_r.c index 1a15b314d0f12..ac0f37050a31f 100644 --- a/system/lib/libc/musl/src/time/localtime_r.c +++ b/system/lib/libc/musl/src/time/localtime_r.c @@ -4,12 +4,18 @@ struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm) { + /* Unlike other musl targets emscripten uses `int` for time_t rather than + * `int64`, so these checks don't apply (they rightly trigger + * `autological-constant-out-of-range-compare` warnings). + * TODO(sbc): Remove this if/when we switch to using int64 too. */ +#ifndef __EMSCRIPTEN__ /* Reject time_t values whose year would overflow int because * __secs_to_zone cannot safely handle them. */ if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) { errno = EOVERFLOW; return 0; } +#endif __secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone); if (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) { errno = EOVERFLOW; diff --git a/system/lib/libc/musl/src/time/strftime.c b/system/lib/libc/musl/src/time/strftime.c index c40246dbb0fa3..59d609ba92245 100644 --- a/system/lib/libc/musl/src/time/strftime.c +++ b/system/lib/libc/musl/src/time/strftime.c @@ -226,7 +226,13 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st s[l] = 0; return l; } +#ifdef __EMSCRIPTEN__ + // Handle trailing % by outputting a % rather than returning 0. Ideally + // this 6 character change could be upstreamed into musl... + if (*f != '%' || !f[1]) { +#else if (*f != '%') { +#endif s[l++] = *f; continue; } diff --git a/system/lib/libc/musl/src/unistd/close.c b/system/lib/libc/musl/src/unistd/close.c index a2105f5060e23..5a453ff3324da 100644 --- a/system/lib/libc/musl/src/unistd/close.c +++ b/system/lib/libc/musl/src/unistd/close.c @@ -13,7 +13,13 @@ weak_alias(dummy, __aio_close); int close(int fd) { fd = __aio_close(fd); +#ifdef __EMSCRIPTEN__ + int r = __wasi_fd_close(fd); + if (r == __WASI_ERRNO_INTR) r = __WASI_ERRNO_SUCCESS; + return __wasi_syscall_ret(r); +#else int r = __syscall_cp(SYS_close, fd); if (r == -EINTR) r = 0; return __syscall_ret(r); +#endif } diff --git a/system/lib/libc/musl/src/unistd/dup2.c b/system/lib/libc/musl/src/unistd/dup2.c index 8f43c6ddfe898..793cfba1c7de8 100644 --- a/system/lib/libc/musl/src/unistd/dup2.c +++ b/system/lib/libc/musl/src/unistd/dup2.c @@ -1,3 +1,6 @@ +#ifdef __EMSCRIPTEN__ +#include +#endif #include #include #include @@ -10,7 +13,11 @@ int dup2(int old, int new) while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); #else if (old==new) { +#ifdef __EMSCRIPTEN__ + r = __wasi_fd_is_valid(old) ? 0 : -EBADF; +#else r = __syscall(SYS_fcntl, old, F_GETFD); +#endif if (r >= 0) return old; } else { while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY); diff --git a/system/lib/libc/musl/src/unistd/faccessat.c b/system/lib/libc/musl/src/unistd/faccessat.c index 43052dd70eeeb..bfc709d108472 100644 --- a/system/lib/libc/musl/src/unistd/faccessat.c +++ b/system/lib/libc/musl/src/unistd/faccessat.c @@ -4,6 +4,7 @@ #include "syscall.h" #include "pthread_impl.h" +#ifndef __EMSCRIPTEN__ struct ctx { int fd; const char *filename; @@ -22,9 +23,13 @@ static int checker(void *p) __syscall(SYS_write, c->p, &ret, sizeof ret); return 0; } +#endif int faccessat(int fd, const char *filename, int amode, int flag) { +#ifdef __EMSCRIPTEN__ + return syscall(SYS_faccessat, fd, filename, amode, flag); +#else if (flag) { int ret = __syscall(SYS_faccessat2, fd, filename, amode, flag); if (ret != -ENOSYS) return __syscall_ret(ret); @@ -58,4 +63,5 @@ int faccessat(int fd, const char *filename, int amode, int flag) __restore_sigs(&set); return __syscall_ret(ret); +#endif } diff --git a/system/lib/libc/musl/src/unistd/fchdir.c b/system/lib/libc/musl/src/unistd/fchdir.c index dee45ba68e642..bcbd0fc9cc9cd 100644 --- a/system/lib/libc/musl/src/unistd/fchdir.c +++ b/system/lib/libc/musl/src/unistd/fchdir.c @@ -1,3 +1,6 @@ +#ifdef __EMSCRIPTEN__ +#include +#endif #include #include #include @@ -6,8 +9,13 @@ int fchdir(int fd) { int ret = __syscall(SYS_fchdir, fd); +#if __EMSCRIPTEN__ + if (ret != -EBADF || !__wasi_fd_is_valid(fd)) + return __syscall_ret(ret); +#else if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); +#endif char buf[15+3*sizeof(int)]; __procfdname(buf, fd); diff --git a/system/lib/libc/musl/src/unistd/fchown.c b/system/lib/libc/musl/src/unistd/fchown.c index 737b3672fcce5..a328189505444 100644 --- a/system/lib/libc/musl/src/unistd/fchown.c +++ b/system/lib/libc/musl/src/unistd/fchown.c @@ -1,3 +1,6 @@ +#ifdef __EMSCRIPTEN__ +#include +#endif #include #include #include @@ -6,6 +9,11 @@ int fchown(int fd, uid_t uid, gid_t gid) { int ret = __syscall(SYS_fchown, fd, uid, gid); +#if __EMSCRIPTEN__ + // We can't continue onwards to try the /proc/fd/NNN approach that musl does, + // as we don't support that much of POSIX. + return __syscall_ret(ret); +#else if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) return __syscall_ret(ret); @@ -16,5 +24,5 @@ int fchown(int fd, uid_t uid, gid_t gid) #else return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0); #endif - +#endif // EMSCRIPTEN } diff --git a/system/lib/libc/musl/src/unistd/fsync.c b/system/lib/libc/musl/src/unistd/fsync.c index 7a1c80b5de0d8..2b26be534e96c 100644 --- a/system/lib/libc/musl/src/unistd/fsync.c +++ b/system/lib/libc/musl/src/unistd/fsync.c @@ -3,5 +3,9 @@ int fsync(int fd) { +#if __EMSCRIPTEN__ + return __wasi_syscall_ret(__wasi_fd_sync(fd)); +#else return syscall_cp(SYS_fsync, fd); +#endif } diff --git a/system/lib/libc/musl/src/unistd/isatty.c b/system/lib/libc/musl/src/unistd/isatty.c index 21222edab6ee5..fe922d465bffb 100644 --- a/system/lib/libc/musl/src/unistd/isatty.c +++ b/system/lib/libc/musl/src/unistd/isatty.c @@ -5,7 +5,25 @@ int isatty(int fd) { +#ifdef __EMSCRIPTEN__ + __wasi_fdstat_t statbuf; + int err = __wasi_fd_fdstat_get(fd, &statbuf); + if (err != 0) { + errno = err; + return 0; + } + + // All character devices are terminals (other things a Linux system would + // assume is a character device, like the mouse, we have special APIs for). + if (statbuf.fs_filetype != __WASI_FILETYPE_CHARACTER_DEVICE) { + errno = __WASI_ERRNO_NOTTY; + return 0; + } + + return 1; +#else struct winsize wsz; /* +1 converts from error status (0/-1) to boolean (1/0) */ return syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz) + 1; +#endif } diff --git a/system/lib/libc/musl/src/unistd/lseek.c b/system/lib/libc/musl/src/unistd/lseek.c index f5b66682abc46..199e784c01d74 100644 --- a/system/lib/libc/musl/src/unistd/lseek.c +++ b/system/lib/libc/musl/src/unistd/lseek.c @@ -3,12 +3,17 @@ off_t __lseek(int fd, off_t offset, int whence) { +#ifdef __EMSCRIPTEN__ + off_t result; + return __wasi_syscall_ret(__wasi_fd_seek(fd, offset, whence, &result)) ? -1 : result; +#else #ifdef SYS__llseek off_t result; return syscall(SYS__llseek, fd, offset>>32, offset, &result, whence) ? -1 : result; #else return syscall(SYS_lseek, fd, offset, whence); #endif +#endif // __EMSCRIPTEN__ } weak_alias(__lseek, lseek); diff --git a/system/lib/libc/musl/src/unistd/pipe2.c b/system/lib/libc/musl/src/unistd/pipe2.c index a096990b1503d..f215000b31c4d 100644 --- a/system/lib/libc/musl/src/unistd/pipe2.c +++ b/system/lib/libc/musl/src/unistd/pipe2.c @@ -11,10 +11,12 @@ int pipe2(int fd[2], int flag) if (flag & ~(O_CLOEXEC|O_NONBLOCK)) return __syscall_ret(-EINVAL); ret = pipe(fd); if (ret) return ret; +#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process if (flag & O_CLOEXEC) { __syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC); __syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC); } +#endif if (flag & O_NONBLOCK) { __syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK); __syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK); diff --git a/system/lib/libc/musl/src/unistd/pread.c b/system/lib/libc/musl/src/unistd/pread.c index b03fb0ad94076..a2361a0473b51 100644 --- a/system/lib/libc/musl/src/unistd/pread.c +++ b/system/lib/libc/musl/src/unistd/pread.c @@ -3,5 +3,17 @@ ssize_t pread(int fd, void *buf, size_t size, off_t ofs) { +#if __EMSCRIPTEN__ + __wasi_iovec_t iov = { + .buf = buf, + .buf_len = size + }; + size_t num; + if (__wasi_syscall_ret(__wasi_fd_pread(fd, &iov, 1, ofs, &num))) { + return -1; + } + return num; +#else return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs)); +#endif } diff --git a/system/lib/libc/musl/src/unistd/preadv.c b/system/lib/libc/musl/src/unistd/preadv.c index 890ab403f9dbd..fa6b78c101b3f 100644 --- a/system/lib/libc/musl/src/unistd/preadv.c +++ b/system/lib/libc/musl/src/unistd/preadv.c @@ -5,6 +5,14 @@ ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs) { +#if __EMSCRIPTEN__ + size_t num; + if (__wasi_syscall_ret(__wasi_fd_pread(fd, (struct __wasi_iovec_t*)iov, count, ofs, &num))) { + return -1; + } + return num; +#else return syscall_cp(SYS_preadv, fd, iov, count, (long)(ofs), (long)(ofs>>32)); +#endif } diff --git a/system/lib/libc/musl/src/unistd/pwrite.c b/system/lib/libc/musl/src/unistd/pwrite.c index a008b3ecb5a45..4b2035ade9ea4 100644 --- a/system/lib/libc/musl/src/unistd/pwrite.c +++ b/system/lib/libc/musl/src/unistd/pwrite.c @@ -6,6 +6,17 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { +#if __EMSCRIPTEN__ + __wasi_ciovec_t iov = { + .buf = buf, + .buf_len = size + }; + size_t num; + if (__wasi_syscall_ret(__wasi_fd_pwrite(fd, &iov, 1, ofs, &num))) { + return -1; + } + return num; +#else if (ofs == -1) ofs--; int r = __syscall_cp(SYS_pwritev2, fd, (&(struct iovec){ .iov_base = (void *)buf, .iov_len = size }), @@ -15,4 +26,5 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) if (fcntl(fd, F_GETFL) & O_APPEND) return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs)); +#endif } diff --git a/system/lib/libc/musl/src/unistd/pwritev.c b/system/lib/libc/musl/src/unistd/pwritev.c index 44a53d8576274..d4f03899d73d0 100644 --- a/system/lib/libc/musl/src/unistd/pwritev.c +++ b/system/lib/libc/musl/src/unistd/pwritev.c @@ -6,6 +6,13 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { +#if __EMSCRIPTEN__ + size_t num; + if (__wasi_syscall_ret(__wasi_fd_pwrite(fd, (struct __wasi_ciovec_t*)iov, count, ofs, &num))) { + return -1; + } + return num; +#else if (ofs == -1) ofs--; int r = __syscall_cp(SYS_pwritev2, fd, iov, count, (long)(ofs), (long)(ofs>>32), RWF_NOAPPEND); @@ -15,4 +22,5 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) return __syscall_ret(-EOPNOTSUPP); return syscall_cp(SYS_pwritev, fd, iov, count, (long)(ofs), (long)(ofs>>32)); +#endif } diff --git a/system/lib/libc/musl/src/unistd/read.c b/system/lib/libc/musl/src/unistd/read.c index f3589c05c3e3b..f079439c9d302 100644 --- a/system/lib/libc/musl/src/unistd/read.c +++ b/system/lib/libc/musl/src/unistd/read.c @@ -3,5 +3,17 @@ ssize_t read(int fd, void *buf, size_t count) { +#if __EMSCRIPTEN__ + __wasi_iovec_t iov = { + .buf = buf, + .buf_len = count + }; + size_t num; + if (__wasi_syscall_ret(__wasi_fd_read(fd, &iov, 1, &num))) { + return -1; + } + return num; +#else return syscall_cp(SYS_read, fd, buf, count); +#endif } diff --git a/system/lib/libc/musl/src/unistd/readv.c b/system/lib/libc/musl/src/unistd/readv.c index 91e6de8167793..bb0760da6e147 100644 --- a/system/lib/libc/musl/src/unistd/readv.c +++ b/system/lib/libc/musl/src/unistd/readv.c @@ -3,5 +3,13 @@ ssize_t readv(int fd, const struct iovec *iov, int count) { +#if __EMSCRIPTEN__ + size_t num; + if (__wasi_syscall_ret(__wasi_fd_read(fd, (struct __wasi_iovec_t*)iov, count, &num))) { + num = -1; + } + return num; +#else return syscall_cp(SYS_readv, fd, iov, count); +#endif } diff --git a/system/lib/libc/musl/src/unistd/setxid.c b/system/lib/libc/musl/src/unistd/setxid.c index a629ed4b46e57..ab707276a32cd 100644 --- a/system/lib/libc/musl/src/unistd/setxid.c +++ b/system/lib/libc/musl/src/unistd/setxid.c @@ -3,6 +3,12 @@ #include "syscall.h" #include "libc.h" +#ifdef __EMSCRIPTEN__ +int __setxid_emscripten() { + errno = EPERM; // we don't allow dynamic syscalls, and don't need to support these anyhow + return -1; +} +#else struct ctx { int id, eid, sid; int nr, ret; @@ -21,7 +27,7 @@ static void do_setxid(void *p) __block_all_sigs(0); __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL); } - c->ret = ret; + c->err = ret; } int __setxid(int nr, int id, int eid, int sid) @@ -32,3 +38,4 @@ int __setxid(int nr, int id, int eid, int sid) __synccall(do_setxid, &c); return __syscall_ret(c.ret > 0 ? -EAGAIN : c.ret); } +#endif diff --git a/system/lib/libc/musl/src/unistd/write.c b/system/lib/libc/musl/src/unistd/write.c index 8fd5bc5c261ce..53742cd4fd972 100644 --- a/system/lib/libc/musl/src/unistd/write.c +++ b/system/lib/libc/musl/src/unistd/write.c @@ -3,5 +3,17 @@ ssize_t write(int fd, const void *buf, size_t count) { +#if __EMSCRIPTEN__ + __wasi_ciovec_t iov = { + .buf = buf, + .buf_len = count + }; + size_t num; + if (__wasi_syscall_ret(__wasi_fd_write(fd, &iov, 1, &num))) { + return -1; + } + return num; +#else return syscall_cp(SYS_write, fd, buf, count); +#endif } diff --git a/system/lib/libc/musl/src/unistd/writev.c b/system/lib/libc/musl/src/unistd/writev.c index 5a46c951af57c..443d14f35d1be 100644 --- a/system/lib/libc/musl/src/unistd/writev.c +++ b/system/lib/libc/musl/src/unistd/writev.c @@ -1,7 +1,18 @@ #include #include "syscall.h" +#if __EMSCRIPTEN__ +#include +#endif ssize_t writev(int fd, const struct iovec *iov, int count) { +#if __EMSCRIPTEN__ + size_t num; + if (__wasi_syscall_ret(__wasi_fd_write(fd, (struct __wasi_ciovec_t*)iov, count, &num))) { + return -1; + } + return num; +#else return syscall_cp(SYS_writev, fd, iov, count); +#endif } diff --git a/system/lib/libc/musl/tools/mkalltypes.sed b/system/lib/libc/musl/tools/mkalltypes.sed new file mode 100644 index 0000000000000..fa15efc35f64e --- /dev/null +++ b/system/lib/libc/musl/tools/mkalltypes.sed @@ -0,0 +1,15 @@ +/^TYPEDEF/s/TYPEDEF \(.*\) \([^ ]*\);$/#if defined(__NEED_\2) \&\& !defined(__DEFINED_\2)\ +typedef \1 \2;\ +#define __DEFINED_\2\ +#endif\ +/ +/^STRUCT/s/STRUCT * \([^ ]*\) \(.*\);$/#if defined(__NEED_struct_\1) \&\& !defined(__DEFINED_struct_\1)\ +struct \1 \2;\ +#define __DEFINED_struct_\1\ +#endif\ +/ +/^UNION/s/UNION * \([^ ]*\) \(.*\);$/#if defined(__NEED_union_\1) \&\& !defined(__DEFINED_union_\1)\ +union \1 \2;\ +#define __DEFINED_union_\1\ +#endif\ +/ From 82cc2d33bf5713c6a960ca0b0613f36c9a76509a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 6 Dec 2020 21:30:39 +0100 Subject: [PATCH 05/17] Revise Emscripten-specific changes --- system/lib/libc/README.md | 3 +- system/lib/libc/musl/include/setjmp.h | 2 +- system/lib/libc/musl/src/exit/abort.c | 4 +- system/lib/libc/musl/src/internal/libm.h | 17 ++++--- .../lib/libc/musl/src/internal/locale_impl.h | 2 +- .../lib/libc/musl/src/internal/pthread_impl.h | 2 +- system/lib/libc/musl/src/internal/syscall.h | 51 +++++++++---------- system/lib/libc/musl/src/linux/sbrk.c | 3 +- system/lib/libc/musl/src/math/sqrt.c | 2 +- system/lib/libc/musl/src/math/sqrtf.c | 2 +- .../lib/libc/musl/src/network/freeaddrinfo.c | 2 +- system/lib/libc/musl/src/sched/sched_yield.c | 4 +- system/lib/libc/musl/src/stat/fchmod.c | 2 +- system/lib/libc/musl/src/stat/fstatat.c | 2 +- system/lib/libc/musl/src/stdio/__stdio_read.c | 3 +- .../lib/libc/musl/src/stdio/__stdio_write.c | 2 +- system/lib/libc/musl/src/stdio/stdout.c | 4 +- system/lib/libc/musl/src/stdio/vfprintf.c | 2 +- system/lib/libc/musl/src/string/memcmp.c | 2 +- system/lib/libc/musl/src/thread/__timedwait.c | 4 +- .../musl/src/thread/pthread_mutex_timedlock.c | 2 +- system/lib/libc/musl/src/time/clock_gettime.c | 2 +- .../lib/libc/musl/src/time/clock_nanosleep.c | 4 +- system/lib/libc/musl/src/time/clock_settime.c | 7 +-- system/lib/libc/musl/src/unistd/fchdir.c | 2 +- system/lib/libc/musl/src/unistd/fchown.c | 4 +- system/lib/libc/musl/src/unistd/fsync.c | 2 +- system/lib/libc/musl/src/unistd/pread.c | 2 +- system/lib/libc/musl/src/unistd/preadv.c | 2 +- system/lib/libc/musl/src/unistd/pwrite.c | 2 +- system/lib/libc/musl/src/unistd/pwritev.c | 2 +- system/lib/libc/musl/src/unistd/read.c | 2 +- system/lib/libc/musl/src/unistd/readv.c | 2 +- system/lib/libc/musl/src/unistd/write.c | 2 +- system/lib/libc/musl/src/unistd/writev.c | 4 +- 35 files changed, 76 insertions(+), 80 deletions(-) diff --git a/system/lib/libc/README.md b/system/lib/libc/README.md index e970933eb771a..8b4b6f8125186 100644 --- a/system/lib/libc/README.md +++ b/system/lib/libc/README.md @@ -7,8 +7,7 @@ and use a script (`system/lib/update_musl.py`) to pull in updates. Some changes have been made to the version that was taken from upstream, including: - * Emscripten-specific changes (from before this readme existed). These should be marked with `XXX EMSCRIPTEN` in the source, or ifdefed with `#if __EMSCRIPTEN__`. They are mostly in pthreads code and hopefully temporary. - * Backporting an operator-precedence warning fix from 6e76e1540fc58a418494bf5eb832b556f9c5763e in the upstream version. + * Emscripten-specific changes (from before this readme existed). These should be marked with `XXX EMSCRIPTEN` in the source, or ifdefed with `#ifdef __EMSCRIPTEN__`. They are mostly in pthreads code and hopefully temporary. * Switch to using the wasi `fd_write` syscall instead of `writev`. * Simplify stdout stream handling: do not support seeking, terminal handling, etc., as it just increases code size and Emscripten doesn't have those features anyhow. * Setting `_POSIX_REALTIME_SIGNALS` and `_POSIX_SPAWN` macros to -1, to exclude unsupported functions. diff --git a/system/lib/libc/musl/include/setjmp.h b/system/lib/libc/musl/include/setjmp.h index af72c80cdbce0..5aabfa95c4a05 100644 --- a/system/lib/libc/musl/include/setjmp.h +++ b/system/lib/libc/musl/include/setjmp.h @@ -26,7 +26,7 @@ typedef struct __jmp_buf_tag { || defined(_BSD_SOURCE) typedef jmp_buf sigjmp_buf; /* XXX EMSCRIPTEN: No signals support, alias sigsetjmp and siglongjmp to their non-signals counterparts. */ -#if __EMSCRIPTEN__ && !defined(LLVM_LIBC) +#if defined(__EMSCRIPTEN__) && !defined(LLVM_LIBC) #define sigsetjmp(buf, x) setjmp((buf)) #define siglongjmp(buf, val) longjmp(buf, val) #else diff --git a/system/lib/libc/musl/src/exit/abort.c b/system/lib/libc/musl/src/exit/abort.c index a6427d51d66e9..8ff8a8626ee07 100644 --- a/system/lib/libc/musl/src/exit/abort.c +++ b/system/lib/libc/musl/src/exit/abort.c @@ -6,13 +6,13 @@ #include "lock.h" #include "ksigaction.h" -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ #include "emscripten_internal.h" #endif _Noreturn void abort(void) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ /* In emscripten we call out to JS to perform the actual abort where it can * produce a nice error. * Note that the JS library function is not called `abort` to avoid conflict diff --git a/system/lib/libc/musl/src/internal/libm.h b/system/lib/libc/musl/src/internal/libm.h index a47208aa6ad3c..9d8b892d5b3e8 100644 --- a/system/lib/libc/musl/src/internal/libm.h +++ b/system/lib/libc/musl/src/internal/libm.h @@ -144,6 +144,16 @@ static inline long double fp_barrierl(long double x) } #endif +#ifdef __EMSCRIPTEN__ +/* + * wasm doesn't have user-accessible floating point exceptions, so there's + * no point in trying to force expression evaluations to produce them. + */ +#define fp_force_evalf(x) +#define fp_force_eval(x) +#define fp_force_evall(x) +#define FORCE_EVAL(x) +#else /* fp_force_eval ensures that the input value is computed when that's otherwise unused. To prevent the constant folding of the input expression, an additional fp_barrier may be needed or a compilation @@ -177,13 +187,6 @@ static inline void fp_force_evall(long double x) } #endif -#ifdef __EMSCRIPTEN__ -/* - * asm.js doesn't have user-accessible floating point exceptions, so there's - * no point in trying to force expression evaluations to produce them. - */ -#define FORCE_EVAL(x) -#else #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ fp_force_evalf(x); \ diff --git a/system/lib/libc/musl/src/internal/locale_impl.h b/system/lib/libc/musl/src/internal/locale_impl.h index 9a7b07c4aac0e..1f46f88fa7d74 100644 --- a/system/lib/libc/musl/src/internal/locale_impl.h +++ b/system/lib/libc/musl/src/internal/locale_impl.h @@ -31,7 +31,7 @@ hidden char *__gettextdomain(void); #define LOC_MAP_FAILED ((const struct __locale_map *)-1) -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // Disable message translation completely under emscripten since we don't // support loading any actual locale data, and even looking up the current // local via CURRENT_LOCALE via TLS is not free. diff --git a/system/lib/libc/musl/src/internal/pthread_impl.h b/system/lib/libc/musl/src/internal/pthread_impl.h index a366b6cef8eb3..d7978ba8fccf7 100644 --- a/system/lib/libc/musl/src/internal/pthread_impl.h +++ b/system/lib/libc/musl/src/internal/pthread_impl.h @@ -237,7 +237,7 @@ static inline void __wake(volatile void *addr, int cnt, int priv) if (priv) priv = FUTEX_PRIVATE; if (cnt<0) cnt = INT_MAX; #ifdef __EMSCRIPTEN__ - emscripten_futex_wake(addr, (cnt)<0?INT_MAX:(cnt)); + emscripten_futex_wake(addr, cnt); #else __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); diff --git a/system/lib/libc/musl/src/internal/syscall.h b/system/lib/libc/musl/src/internal/syscall.h index 4476dbe7db09a..22fc5f146c8b5 100644 --- a/system/lib/libc/musl/src/internal/syscall.h +++ b/system/lib/libc/musl/src/internal/syscall.h @@ -30,7 +30,7 @@ typedef long syscall_arg_t; #endif -#ifdef __cplusplus +#ifdef __cplusplus // XXX Emscripten we need C linkage for this extern "C" { #endif hidden long __syscall_ret(unsigned long), @@ -40,14 +40,7 @@ hidden long __syscall_ret(unsigned long), } #endif -#ifndef __EMSCRIPTEN__ -#define __syscall1(n,a) __syscall1(n,__scc(a)) -#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) -#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) -#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) -#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) -#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#else // __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ #define __syscall_emscripten(n, ...) n(__VA_ARGS__) #define __syscall_emscripten0(n) __syscall_emscripten(n) #define __syscall_emscripten1(n,a) __syscall_emscripten(n,__scc(a)) @@ -56,7 +49,14 @@ hidden long __syscall_ret(unsigned long), #define __syscall_emscripten4(n,a,b,c,d) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d)) #define __syscall_emscripten5(n,a,b,c,d,e) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) #define __syscall_emscripten6(n,a,b,c,d,e,f) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#endif // __EMSCRIPTEN__ +#else // !defined(__EMSCRIPTEN__) +#define __syscall1(n,a) __syscall1(n,__scc(a)) +#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) +#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) +#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) +#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) +#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) +#endif // !defined(__EMSCRIPTEN__) #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,) @@ -64,10 +64,10 @@ hidden long __syscall_ret(unsigned long), #define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b) #define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) -#ifndef __EMSCRIPTEN__ -#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) -#else +#ifdef __EMSCRIPTEN__ #define __syscall(...) __SYSCALL_DISP(__syscall_emscripten,__VA_ARGS__) +#else +#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) #endif #define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) @@ -75,7 +75,9 @@ hidden long __syscall_ret(unsigned long), #define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f)) #define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f)) -#ifndef __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ +#define __syscall_cp(...) __syscall(__VA_ARGS__) +#else // !defined(__EMSCRIPTEN__) #define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0) #define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0) #define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0) @@ -85,9 +87,7 @@ hidden long __syscall_ret(unsigned long), #define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) -#else // __EMSCRIPTEN__ -#define __syscall_cp(...) __syscall(__VA_ARGS__) -#endif // __EMSCRIPTEN__ +#endif // !defined(__EMSCRIPTEN__) #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) @@ -408,7 +408,12 @@ hidden long __syscall_ret(unsigned long), #define SIOCGSTAMPNS_OLD 0x8907 #endif -#ifndef __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ +#define __sys_open2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) +#define __sys_open3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) +#define __sys_open_cp2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) +#else // !defined(__EMSCRIPTEN__) #ifdef SYS_open #define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) #define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) @@ -420,13 +425,7 @@ hidden long __syscall_ret(unsigned long), #define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) #define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) #endif -#else // __EMSCRIPTEN__ -#define __sys_open2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) -#define __sys_open3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) -#define __sys_open_cp2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) -#define __sys_open_cp3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) -#endif - +#endif // !defined(__EMSCRIPTEN__) #define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__) #define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__)) @@ -456,7 +455,7 @@ hidden long __emulate_wait4(int, int *, int, void *, int); #define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d)) #define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d)) -#ifdef __cplusplus +#ifdef __cplusplus // XXX Emscripten static array size is a C99 feature, not permitted in C++ hidden void __procfdname(char __buf[], unsigned); #else hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); diff --git a/system/lib/libc/musl/src/linux/sbrk.c b/system/lib/libc/musl/src/linux/sbrk.c index 8e3a9b6645d68..cf483a57fb329 100644 --- a/system/lib/libc/musl/src/linux/sbrk.c +++ b/system/lib/libc/musl/src/linux/sbrk.c @@ -1,4 +1,4 @@ -#if !__EMSCRIPTEN__ /* Emscripten controls sbrk itself */ +#ifndef __EMSCRIPTEN__ /* Emscripten controls sbrk itself */ #define _BSD_SOURCE #include #include @@ -11,4 +11,3 @@ void *sbrk(intptr_t inc) return (void *)__syscall(SYS_brk, 0); } #endif - diff --git a/system/lib/libc/musl/src/math/sqrt.c b/system/lib/libc/musl/src/math/sqrt.c index 6854c98381642..3b07abee8380a 100644 --- a/system/lib/libc/musl/src/math/sqrt.c +++ b/system/lib/libc/musl/src/math/sqrt.c @@ -27,7 +27,7 @@ double sqrt(double x) { // XXX EMSCRIPTEN: use the wasm instruction via clang builtin // See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ +#ifdef __EMSCRIPTEN__ return __builtin_sqrt(x); #else uint64_t ix, top, m; diff --git a/system/lib/libc/musl/src/math/sqrtf.c b/system/lib/libc/musl/src/math/sqrtf.c index fd74702691215..d1f3b9595ccd0 100644 --- a/system/lib/libc/musl/src/math/sqrtf.c +++ b/system/lib/libc/musl/src/math/sqrtf.c @@ -18,7 +18,7 @@ float sqrtf(float x) { // XXX EMSCRIPTEN: use the wasm instruction via clang builtin // See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __wasm__ +#ifdef __EMSCRIPTEN__ return __builtin_sqrtf(x); #else uint32_t ix, m, m1, m0, even, ey; diff --git a/system/lib/libc/musl/src/network/freeaddrinfo.c b/system/lib/libc/musl/src/network/freeaddrinfo.c index c4016d9f7c246..68fdc09cb9e10 100644 --- a/system/lib/libc/musl/src/network/freeaddrinfo.c +++ b/system/lib/libc/musl/src/network/freeaddrinfo.c @@ -6,7 +6,7 @@ void freeaddrinfo(struct addrinfo *p) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // Emscripten's usage of this structure is very simple: we always allocate // ai_addr, and do not use the linked list aspect at all. There is also no // aliasing with aibuf. diff --git a/system/lib/libc/musl/src/sched/sched_yield.c b/system/lib/libc/musl/src/sched/sched_yield.c index 7bd3846fc239e..82a14a3914e95 100644 --- a/system/lib/libc/musl/src/sched/sched_yield.c +++ b/system/lib/libc/musl/src/sched/sched_yield.c @@ -1,7 +1,7 @@ #include #include "syscall.h" -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ #include #include #include "threading_internal.h" @@ -9,7 +9,7 @@ int sched_yield() { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // SharedArrayBuffer and wasm threads do not support explicit yielding. // For now we at least call `emscripten_yield` which processes the event queue // (along with other essential tasks). diff --git a/system/lib/libc/musl/src/stat/fchmod.c b/system/lib/libc/musl/src/stat/fchmod.c index 58badd5c01bb8..ca2a6c783b2bd 100644 --- a/system/lib/libc/musl/src/stat/fchmod.c +++ b/system/lib/libc/musl/src/stat/fchmod.c @@ -9,7 +9,7 @@ int fchmod(int fd, mode_t mode) { int ret = __syscall(SYS_fchmod, fd, mode); -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ if (ret != -EBADF || !__wasi_fd_is_valid(fd)) return __syscall_ret(ret); #else diff --git a/system/lib/libc/musl/src/stat/fstatat.c b/system/lib/libc/musl/src/stat/fstatat.c index 631451268c590..6d499c44174a3 100644 --- a/system/lib/libc/musl/src/stat/fstatat.c +++ b/system/lib/libc/musl/src/stat/fstatat.c @@ -145,7 +145,7 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag) { int ret; -#ifdef __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // XXX Emscripten statx syscall unsupported // some logic here copied from fstatat_kstat above if (flag==AT_EMPTY_PATH && fd>=0 && !*path) ret = __syscall(SYS_fstat, fd, st); diff --git a/system/lib/libc/musl/src/stdio/__stdio_read.c b/system/lib/libc/musl/src/stdio/__stdio_read.c index 392a4858281f3..c7adefe079f01 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_read.c +++ b/system/lib/libc/musl/src/stdio/__stdio_read.c @@ -8,8 +8,7 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) { .iov_base = f->buf, .iov_len = f->buf_size } }; ssize_t cnt; - -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_read(f->fd, (struct __wasi_iovec_t*)iov, 2, &num))) { num = -1; diff --git a/system/lib/libc/musl/src/stdio/__stdio_write.c b/system/lib/libc/musl/src/stdio/__stdio_write.c index 7a125b89b928d..b2de95cc7790e 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_write.c +++ b/system/lib/libc/musl/src/stdio/__stdio_write.c @@ -17,7 +17,7 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) iovcnt--; } for (;;) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_write(f->fd, (struct __wasi_ciovec_t*)iov, iovcnt, &num))) { num = -1; diff --git a/system/lib/libc/musl/src/stdio/stdout.c b/system/lib/libc/musl/src/stdio/stdout.c index 62cf40220a5c4..5054e5b6ccc14 100644 --- a/system/lib/libc/musl/src/stdio/stdout.c +++ b/system/lib/libc/musl/src/stdio/stdout.c @@ -1,6 +1,6 @@ #include "stdio_impl.h" -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // Emscripten doesn't support terminal seeking. static off_t __emscripten_stdout_seek(FILE *f, off_t off, int whence) { @@ -23,7 +23,7 @@ hidden FILE __stdout_FILE = { .fd = 1, .flags = F_PERM | F_NORD, .lbf = '\n', -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // avoid stout_write which adds special terminal window size handling, which emscripten doesn't support anyhow .write = __stdio_write, .seek = __emscripten_stdout_seek, diff --git a/system/lib/libc/musl/src/stdio/vfprintf.c b/system/lib/libc/musl/src/stdio/vfprintf.c index 96779841164ce..1bfcb42c9bb06 100644 --- a/system/lib/libc/musl/src/stdio/vfprintf.c +++ b/system/lib/libc/musl/src/stdio/vfprintf.c @@ -147,7 +147,7 @@ typedef void (*pop_arg_long_double_t)(union arg *arg, va_list *ap); static void pop_arg_long_double(union arg *arg, va_list *ap) { - arg->f = va_arg(*ap, long double); + arg->f = va_arg(*ap, long double); } static void pop_arg(union arg *arg, int type, va_list *ap, pop_arg_long_double_t pop_arg_long_double) diff --git a/system/lib/libc/musl/src/string/memcmp.c b/system/lib/libc/musl/src/string/memcmp.c index c93cf8cc97330..ba9ab6d41d3c9 100644 --- a/system/lib/libc/musl/src/string/memcmp.c +++ b/system/lib/libc/musl/src/string/memcmp.c @@ -1,4 +1,4 @@ -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ #include #endif #include diff --git a/system/lib/libc/musl/src/thread/__timedwait.c b/system/lib/libc/musl/src/thread/__timedwait.c index 9e3ccc9849257..51afba0044942 100644 --- a/system/lib/libc/musl/src/thread/__timedwait.c +++ b/system/lib/libc/musl/src/thread/__timedwait.c @@ -32,10 +32,10 @@ static int __futex4_cp(volatile void *addr, int op, int val, const struct timesp if (r != -ENOSYS) return r; return __syscall_cp(SYS_futex, addr, op & ~FUTEX_PRIVATE, val, to); } -#endif static volatile int dummy = 0; weak_alias(dummy, __eintr_valid_flag); +#endif int __timedwait_cp(volatile int *addr, int val, clockid_t clk, const struct timespec *at, int priv) @@ -64,11 +64,13 @@ int __timedwait_cp(volatile int *addr, int val, r = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top); #endif if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0; +#ifndef __EMSCRIPTEN__ // XXX Emscripten revert musl commit a63c0104e496f7ba78b64be3cd299b41e8cd427f /* Mitigate bug in old kernels wrongly reporting EINTR for non- * interrupting (SA_RESTART) signal handlers. This is only practical * when NO interrupting signal handlers have been installed, and * works by sigaction tracking whether that's the case. */ if (r == EINTR && !__eintr_valid_flag) r = 0; +#endif return r; } diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c index 232c9b321a8e2..95eefb45ea0a8 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c @@ -77,7 +77,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec #ifndef __EMSCRIPTEN__ if (type&8) return pthread_mutex_timedlock_pi(m, at); #endif - + int spins = 100; while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); diff --git a/system/lib/libc/musl/src/time/clock_gettime.c b/system/lib/libc/musl/src/time/clock_gettime.c index 18926de8ce8f3..36d901e85dff1 100644 --- a/system/lib/libc/musl/src/time/clock_gettime.c +++ b/system/lib/libc/musl/src/time/clock_gettime.c @@ -56,7 +56,7 @@ static void *volatile vdso_func = (void *)cgt_init; #endif -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ _Static_assert(CLOCK_REALTIME == __WASI_CLOCKID_REALTIME, "monotonic clock must match"); _Static_assert(CLOCK_MONOTONIC == __WASI_CLOCKID_MONOTONIC, "monotonic clock must match"); diff --git a/system/lib/libc/musl/src/time/clock_nanosleep.c b/system/lib/libc/musl/src/time/clock_nanosleep.c index 7ad2aba1a0b7a..3684e43aa14c6 100644 --- a/system/lib/libc/musl/src/time/clock_nanosleep.c +++ b/system/lib/libc/musl/src/time/clock_nanosleep.c @@ -1,7 +1,7 @@ #include #include #include "syscall.h" -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ #include #include #endif @@ -12,7 +12,7 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) { if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL; -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999L || req->tv_sec < 0) { return EINVAL; } diff --git a/system/lib/libc/musl/src/time/clock_settime.c b/system/lib/libc/musl/src/time/clock_settime.c index ed0182fff664c..686488414371a 100644 --- a/system/lib/libc/musl/src/time/clock_settime.c +++ b/system/lib/libc/musl/src/time/clock_settime.c @@ -1,9 +1,6 @@ #include #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ -#include -#endif #define IS32BIT(x) !((x)+0x80000000ULL>>32) @@ -13,8 +10,7 @@ int clock_settime(clockid_t clk, const struct timespec *ts) // JS and wasm VMs do not allow setting the time. errno = EPERM; return -1; -#else -#ifdef SYS_clock_settime64 +#elif defined(SYS_clock_settime64) // XXX EMSCRIPTEN replace #ifdef SYS_clock_settime64 time_t s = ts->tv_sec; long ns = ts->tv_nsec; int r = -ENOSYS; @@ -29,5 +25,4 @@ int clock_settime(clockid_t clk, const struct timespec *ts) #else return syscall(SYS_clock_settime, clk, ts); #endif -#endif } diff --git a/system/lib/libc/musl/src/unistd/fchdir.c b/system/lib/libc/musl/src/unistd/fchdir.c index bcbd0fc9cc9cd..a22f5f4fed65d 100644 --- a/system/lib/libc/musl/src/unistd/fchdir.c +++ b/system/lib/libc/musl/src/unistd/fchdir.c @@ -9,7 +9,7 @@ int fchdir(int fd) { int ret = __syscall(SYS_fchdir, fd); -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ if (ret != -EBADF || !__wasi_fd_is_valid(fd)) return __syscall_ret(ret); #else diff --git a/system/lib/libc/musl/src/unistd/fchown.c b/system/lib/libc/musl/src/unistd/fchown.c index a328189505444..02facc410b5d1 100644 --- a/system/lib/libc/musl/src/unistd/fchown.c +++ b/system/lib/libc/musl/src/unistd/fchown.c @@ -9,7 +9,7 @@ int fchown(int fd, uid_t uid, gid_t gid) { int ret = __syscall(SYS_fchown, fd, uid, gid); -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ // We can't continue onwards to try the /proc/fd/NNN approach that musl does, // as we don't support that much of POSIX. return __syscall_ret(ret); @@ -24,5 +24,5 @@ int fchown(int fd, uid_t uid, gid_t gid) #else return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0); #endif -#endif // EMSCRIPTEN +#endif // __EMSCRIPTEN__ } diff --git a/system/lib/libc/musl/src/unistd/fsync.c b/system/lib/libc/musl/src/unistd/fsync.c index 2b26be534e96c..8c6c1d13dcc5d 100644 --- a/system/lib/libc/musl/src/unistd/fsync.c +++ b/system/lib/libc/musl/src/unistd/fsync.c @@ -3,7 +3,7 @@ int fsync(int fd) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ return __wasi_syscall_ret(__wasi_fd_sync(fd)); #else return syscall_cp(SYS_fsync, fd); diff --git a/system/lib/libc/musl/src/unistd/pread.c b/system/lib/libc/musl/src/unistd/pread.c index a2361a0473b51..7b790d47d1abc 100644 --- a/system/lib/libc/musl/src/unistd/pread.c +++ b/system/lib/libc/musl/src/unistd/pread.c @@ -3,7 +3,7 @@ ssize_t pread(int fd, void *buf, size_t size, off_t ofs) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ __wasi_iovec_t iov = { .buf = buf, .buf_len = size diff --git a/system/lib/libc/musl/src/unistd/preadv.c b/system/lib/libc/musl/src/unistd/preadv.c index fa6b78c101b3f..5c86d09cf2c7d 100644 --- a/system/lib/libc/musl/src/unistd/preadv.c +++ b/system/lib/libc/musl/src/unistd/preadv.c @@ -5,7 +5,7 @@ ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_pread(fd, (struct __wasi_iovec_t*)iov, count, ofs, &num))) { return -1; diff --git a/system/lib/libc/musl/src/unistd/pwrite.c b/system/lib/libc/musl/src/unistd/pwrite.c index 4b2035ade9ea4..895afdc5533e3 100644 --- a/system/lib/libc/musl/src/unistd/pwrite.c +++ b/system/lib/libc/musl/src/unistd/pwrite.c @@ -6,7 +6,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ __wasi_ciovec_t iov = { .buf = buf, .buf_len = size diff --git a/system/lib/libc/musl/src/unistd/pwritev.c b/system/lib/libc/musl/src/unistd/pwritev.c index d4f03899d73d0..f011649af40f9 100644 --- a/system/lib/libc/musl/src/unistd/pwritev.c +++ b/system/lib/libc/musl/src/unistd/pwritev.c @@ -6,7 +6,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_pwrite(fd, (struct __wasi_ciovec_t*)iov, count, ofs, &num))) { return -1; diff --git a/system/lib/libc/musl/src/unistd/read.c b/system/lib/libc/musl/src/unistd/read.c index f079439c9d302..f84e9436c7c8b 100644 --- a/system/lib/libc/musl/src/unistd/read.c +++ b/system/lib/libc/musl/src/unistd/read.c @@ -3,7 +3,7 @@ ssize_t read(int fd, void *buf, size_t count) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ __wasi_iovec_t iov = { .buf = buf, .buf_len = count diff --git a/system/lib/libc/musl/src/unistd/readv.c b/system/lib/libc/musl/src/unistd/readv.c index bb0760da6e147..3a40c1e9626f6 100644 --- a/system/lib/libc/musl/src/unistd/readv.c +++ b/system/lib/libc/musl/src/unistd/readv.c @@ -3,7 +3,7 @@ ssize_t readv(int fd, const struct iovec *iov, int count) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_read(fd, (struct __wasi_iovec_t*)iov, count, &num))) { num = -1; diff --git a/system/lib/libc/musl/src/unistd/write.c b/system/lib/libc/musl/src/unistd/write.c index 53742cd4fd972..135229be89121 100644 --- a/system/lib/libc/musl/src/unistd/write.c +++ b/system/lib/libc/musl/src/unistd/write.c @@ -3,7 +3,7 @@ ssize_t write(int fd, const void *buf, size_t count) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ __wasi_ciovec_t iov = { .buf = buf, .buf_len = count diff --git a/system/lib/libc/musl/src/unistd/writev.c b/system/lib/libc/musl/src/unistd/writev.c index 443d14f35d1be..4e81f107f61fb 100644 --- a/system/lib/libc/musl/src/unistd/writev.c +++ b/system/lib/libc/musl/src/unistd/writev.c @@ -1,12 +1,12 @@ #include #include "syscall.h" -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ #include #endif ssize_t writev(int fd, const struct iovec *iov, int count) { -#if __EMSCRIPTEN__ +#ifdef __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_write(fd, (struct __wasi_ciovec_t*)iov, count, &num))) { return -1; From 2bd5f4560d2ad4f093e8e50a6a53a0fa4700eaad Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 7 Dec 2020 12:27:44 +0100 Subject: [PATCH 06/17] Revise Emscripten-specific include changes --- system/lib/libc/musl/include/unistd.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/system/lib/libc/musl/include/unistd.h b/system/lib/libc/musl/include/unistd.h index 59b38fd01d8a0..539cd7c1c9b0e 100644 --- a/system/lib/libc/musl/include/unistd.h +++ b/system/lib/libc/musl/include/unistd.h @@ -240,20 +240,20 @@ pid_t gettid(void); #define _POSIX_NO_TRUNC 1 #define _POSIX_RAW_SOCKETS _POSIX_VERSION -#ifndef __EMSCRIPTEN__ -#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION -#else +#ifdef __EMSCRIPTEN__ #define _POSIX_REALTIME_SIGNALS -1 +#else +#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION #endif #define _POSIX_REGEXP 1 #define _POSIX_SAVED_IDS 1 #define _POSIX_SHELL 1 -#ifndef __EMSCRIPTEN__ -#define _POSIX_SPAWN _POSIX_VERSION -#else +#ifdef __EMSCRIPTEN__ #define _POSIX_SPAWN -1 +#else +#define _POSIX_SPAWN _POSIX_VERSION #endif #define _POSIX_VDISABLE 0 @@ -263,10 +263,10 @@ pid_t gettid(void); #else #define _POSIX_THREADS _POSIX_VERSION #endif -#ifndef __EMSCRIPTEN__ -#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION -#else +#ifdef __EMSCRIPTEN__ #define _POSIX_THREAD_PROCESS_SHARED -1 +#else +#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION #endif #define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION #define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION From 85d99f06fc5a68f6711f269c9edeb74bf6b4a736 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 7 Dec 2020 13:16:13 +0100 Subject: [PATCH 07/17] Revise arch/emscripten/bits changes --- system/lib/libc/musl/arch/emscripten/bits/limits.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/lib/libc/musl/arch/emscripten/bits/limits.h b/system/lib/libc/musl/arch/emscripten/bits/limits.h index 7a09fdc1d175d..b36e964152ea1 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/limits.h +++ b/system/lib/libc/musl/arch/emscripten/bits/limits.h @@ -1 +1,3 @@ -#define PAGE_SIZE 65536 +// A value used historically in Emscripten, and which we don't have a strong +// reason to change so far. +#define PAGESIZE 65536 From e019d33dcf26db17090e2b08790fecbed9ade615 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 11 Dec 2020 13:06:02 +0100 Subject: [PATCH 08/17] Deduplicate arch/emscripten/bits directory --- .../libc/musl/arch/emscripten/bits/endian.h | 1 - .../lib/libc/musl/arch/emscripten/bits/fenv.h | 15 +--- .../lib/libc/musl/arch/emscripten/bits/mman.h | 4 ++ .../libc/musl/arch/emscripten/bits/posix.h | 2 - .../lib/libc/musl/arch/emscripten/bits/reg.h | 6 -- .../libc/musl/arch/emscripten/bits/setjmp.h | 1 + .../libc/musl/arch/emscripten/bits/signal.h | 70 ++++++++++++------- .../lib/libc/musl/arch/emscripten/bits/stat.h | 14 ++-- .../lib/libc/musl/arch/emscripten/bits/user.h | 48 ------------- 9 files changed, 61 insertions(+), 100 deletions(-) delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/endian.h create mode 100644 system/lib/libc/musl/arch/emscripten/bits/mman.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/posix.h delete mode 100644 system/lib/libc/musl/arch/emscripten/bits/reg.h diff --git a/system/lib/libc/musl/arch/emscripten/bits/endian.h b/system/lib/libc/musl/arch/emscripten/bits/endian.h deleted file mode 100644 index 172c338f5080a..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/endian.h +++ /dev/null @@ -1 +0,0 @@ -#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/system/lib/libc/musl/arch/emscripten/bits/fenv.h b/system/lib/libc/musl/arch/emscripten/bits/fenv.h index d3512cb6f7f53..4aff0bd7b95ec 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/fenv.h +++ b/system/lib/libc/musl/arch/emscripten/bits/fenv.h @@ -8,20 +8,7 @@ typedef unsigned short fexcept_t; typedef struct { - unsigned short __control_word; - unsigned short __unused1; - unsigned short __status_word; - unsigned short __unused2; - unsigned short __tags; - unsigned short __unused3; - unsigned int __eip; - unsigned short __cs_selector; - unsigned int __opcode:11; - unsigned int __unused4:5; - unsigned int __data_offset; - unsigned short __data_selector; - unsigned short __unused5; - unsigned int __mxcsr; + unsigned __cw; } fenv_t; #define FE_DFL_ENV ((const fenv_t *) -1) diff --git a/system/lib/libc/musl/arch/emscripten/bits/mman.h b/system/lib/libc/musl/arch/emscripten/bits/mman.h new file mode 100644 index 0000000000000..c52e718d0623f --- /dev/null +++ b/system/lib/libc/musl/arch/emscripten/bits/mman.h @@ -0,0 +1,4 @@ +// XXX Emscripten in sync with both: +// - musl/arch/x86_64/bits/mman.h +// - musl/arch/i386/bits/mman.h +#define MAP_32BIT 0x40 diff --git a/system/lib/libc/musl/arch/emscripten/bits/posix.h b/system/lib/libc/musl/arch/emscripten/bits/posix.h deleted file mode 100644 index 30a38714f36dd..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#define _POSIX_V6_ILP32_OFFBIG 1 -#define _POSIX_V7_ILP32_OFFBIG 1 diff --git a/system/lib/libc/musl/arch/emscripten/bits/reg.h b/system/lib/libc/musl/arch/emscripten/bits/reg.h deleted file mode 100644 index 1c4987c775f11..0000000000000 --- a/system/lib/libc/musl/arch/emscripten/bits/reg.h +++ /dev/null @@ -1,6 +0,0 @@ -#undef __WORDSIZE -#ifdef __wasm64__ -#define __WORDSIZE 64 -#else -#define __WORDSIZE 32 -#endif diff --git a/system/lib/libc/musl/arch/emscripten/bits/setjmp.h b/system/lib/libc/musl/arch/emscripten/bits/setjmp.h index decd26dca07a0..1c9aa40ed60c4 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/setjmp.h +++ b/system/lib/libc/musl/arch/emscripten/bits/setjmp.h @@ -1 +1,2 @@ +// XXX Emscripten in sync with musl/arch/i386/bits/setjmp.h typedef unsigned long __jmp_buf[6]; diff --git a/system/lib/libc/musl/arch/emscripten/bits/signal.h b/system/lib/libc/musl/arch/emscripten/bits/signal.h index 58bc5e2c3a780..231dc9261d885 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/signal.h +++ b/system/lib/libc/musl/arch/emscripten/bits/signal.h @@ -1,3 +1,4 @@ +// XXX Emscripten in sync with musl/arch/i386/bits/signal.h #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) @@ -7,33 +8,46 @@ #endif #ifdef _GNU_SOURCE -#define REG_GS 0 -#define REG_FS 1 -#define REG_ES 2 -#define REG_DS 3 -#define REG_EDI 4 -#define REG_ESI 5 -#define REG_EBP 6 -#define REG_ESP 7 -#define REG_EBX 8 -#define REG_EDX 9 -#define REG_ECX 10 -#define REG_EAX 11 -#define REG_TRAPNO 12 -#define REG_ERR 13 -#define REG_EIP 14 -#define REG_CS 15 -#define REG_EFL 16 -#define REG_UESP 17 -#define REG_SS 18 +enum { REG_GS = 0 }; +#define REG_GS REG_GS +enum { REG_FS = 1 }; +#define REG_FS REG_FS +enum { REG_ES = 2 }; +#define REG_ES REG_ES +enum { REG_DS = 3 }; +#define REG_DS REG_DS +enum { REG_EDI = 4 }; +#define REG_EDI REG_EDI +enum { REG_ESI = 5 }; +#define REG_ESI REG_ESI +enum { REG_EBP = 6 }; +#define REG_EBP REG_EBP +enum { REG_ESP = 7 }; +#define REG_ESP REG_ESP +enum { REG_EBX = 8 }; +#define REG_EBX REG_EBX +enum { REG_EDX = 9 }; +#define REG_EDX REG_EDX +enum { REG_ECX = 10 }; +#define REG_ECX REG_ECX +enum { REG_EAX = 11 }; +#define REG_EAX REG_EAX +enum { REG_TRAPNO = 12 }; +#define REG_TRAPNO REG_TRAPNO +enum { REG_ERR = 13 }; +#define REG_ERR REG_ERR +enum { REG_EIP = 14 }; +#define REG_EIP REG_EIP +enum { REG_CS = 15 }; +#define REG_CS REG_CS +enum { REG_EFL = 16 }; +#define REG_EFL REG_EFL +enum { REG_UESP = 17 }; +#define REG_UESP REG_UESP +enum { REG_SS = 18 }; +#define REG_SS REG_SS #endif -struct sigaltstack { - void *ss_sp; - int ss_flags; - size_t ss_size; -}; - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) typedef int greg_t, gregset_t[19]; typedef struct _fpstate { @@ -64,6 +78,12 @@ typedef struct { } mcontext_t; #endif +struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +}; + typedef struct __ucontext { unsigned long uc_flags; struct __ucontext *uc_link; diff --git a/system/lib/libc/musl/arch/emscripten/bits/stat.h b/system/lib/libc/musl/arch/emscripten/bits/stat.h index bfa9a597bcf6d..e2d91a9b68139 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/stat.h +++ b/system/lib/libc/musl/arch/emscripten/bits/stat.h @@ -1,8 +1,8 @@ +// XXX Emscripten in sync with musl/arch/i386/bits/stat.h except for the padding and 64-bit time_t redirections change. + /* copied from kernel definition, but with padding replaced * by the corresponding correctly-sized userspace types. */ - -struct stat -{ +struct stat { dev_t st_dev; #ifndef __EMSCRIPTEN__ int __st_dev_padding; @@ -19,8 +19,14 @@ struct stat off_t st_size; blksize_t st_blksize; blkcnt_t st_blocks; +#ifndef __EMSCRIPTEN__ // XXX Emscripten no need to activate the symbol redirections for 64-bit time_t. + struct { + long tv_sec; + long tv_nsec; + } __st_atim32, __st_mtim32, __st_ctim32; +#endif + ino_t st_ino; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; - ino_t st_ino; }; diff --git a/system/lib/libc/musl/arch/emscripten/bits/user.h b/system/lib/libc/musl/arch/emscripten/bits/user.h index fa623621eeba3..e69de29bb2d1d 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/user.h +++ b/system/lib/libc/musl/arch/emscripten/bits/user.h @@ -1,48 +0,0 @@ -#undef __WORDSIZE -#define __WORDSIZE 32 - -typedef struct user_fpregs_struct -{ - long cwd, swd, twd, fip, fcs, foo, fos, st_space[20]; -} elf_fpregset_t; - -typedef struct user_fpxregs_struct -{ - unsigned short cwd, swd, twd, fop; - long fip, fcs, foo, fos, mxcsr, reserved; - long st_space[32], xmm_space[32], padding[56]; -} elf_fpxregset_t; - -struct user_regs_struct -{ - long ebx, ecx, edx, esi, edi, ebp, eax, xds, xes, xfs, xgs; - long orig_eax, eip, xcs, eflags, esp, xss; -}; - -#define ELF_NGREG 17 -typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG]; - -struct user -{ - struct user_regs_struct regs; - int u_fpvalid; - struct user_fpregs_struct i387; - unsigned long u_tsize; - unsigned long u_dsize; - unsigned long u_ssize; - unsigned long start_code; - unsigned long start_stack; - long signal; - int reserved; - struct user_regs_struct *u_ar0; - struct user_fpregs_struct *u_fpstate; - unsigned long magic; - char u_comm[32]; - int u_debugreg[8]; -}; - -#define PAGE_MASK (~(PAGE_SIZE-1)) -#define NBPG PAGE_SIZE -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) From b97ab4944803e2b67456c87eae500756a6ba3776 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 12:11:21 +0200 Subject: [PATCH 09/17] Regenerate struct info files Done via: ``` ./tools/gen_struct_info.py ./tools/gen_struct_info.py --wasm64 ``` --- src/struct_info_generated.json | 14 +++++++------- src/struct_info_generated_wasm64.json | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/struct_info_generated.json b/src/struct_info_generated.json index 223558056cd05..f77971b5167ce 100644 --- a/src/struct_info_generated.json +++ b/src/struct_info_generated.json @@ -1077,24 +1077,24 @@ "__size__": 96, "st_atim": { "__size__": 16, - "tv_nsec": 48, - "tv_sec": 40 + "tv_nsec": 56, + "tv_sec": 48 }, "st_blksize": 32, "st_blocks": 36, "st_ctim": { "__size__": 16, - "tv_nsec": 80, - "tv_sec": 72 + "tv_nsec": 88, + "tv_sec": 80 }, "st_dev": 0, "st_gid": 16, - "st_ino": 88, + "st_ino": 40, "st_mode": 4, "st_mtim": { "__size__": 16, - "tv_nsec": 64, - "tv_sec": 56 + "tv_nsec": 72, + "tv_sec": 64 }, "st_nlink": 8, "st_rdev": 20, diff --git a/src/struct_info_generated_wasm64.json b/src/struct_info_generated_wasm64.json index 6d6b9a4f98e21..cca6dc368d5ad 100644 --- a/src/struct_info_generated_wasm64.json +++ b/src/struct_info_generated_wasm64.json @@ -1077,24 +1077,24 @@ "__size__": 104, "st_atim": { "__size__": 16, - "tv_nsec": 56, - "tv_sec": 48 + "tv_nsec": 64, + "tv_sec": 56 }, "st_blksize": 40, "st_blocks": 44, "st_ctim": { "__size__": 16, - "tv_nsec": 88, - "tv_sec": 80 + "tv_nsec": 96, + "tv_sec": 88 }, "st_dev": 0, "st_gid": 20, - "st_ino": 96, + "st_ino": 48, "st_mode": 4, "st_mtim": { "__size__": 16, - "tv_nsec": 72, - "tv_sec": 64 + "tv_nsec": 80, + "tv_sec": 72 }, "st_nlink": 8, "st_rdev": 24, From 0da9cf9857a37b6dc0c673fbe52c4079304d4c9a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 12:13:36 +0200 Subject: [PATCH 10/17] Update README.md and ChangeLog.md --- ChangeLog.md | 1 + system/lib/libc/README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index d70cb2173c030..28034967c6602 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -31,6 +31,7 @@ See docs/process.md for more on how version tagging works. in emscripten. If you still need to support extremely old browsers, you can manually transpile the output of emscripten (e.g. using babel for JS and binaryen for wasm). (#26677) +- musl libc updated from v1.2.5 to v1.2.6. (#26860) 5.0.7 - 04/30/26 ---------------- diff --git a/system/lib/libc/README.md b/system/lib/libc/README.md index 8b4b6f8125186..a540132169a59 100644 --- a/system/lib/libc/README.md +++ b/system/lib/libc/README.md @@ -1,7 +1,7 @@ This folder contains the musl version of libc at `/musl`. The upstream version can be found at http://www.musl-libc.org/. -Most of the source comes from musl v1.2.5, with some exceptions listed below. +Most of the source comes from musl v1.2.6, with some exceptions listed below. We track these changes from upstream in https://github.com/emscripten-core/musl and use a script (`system/lib/update_musl.py`) to pull in updates. From 7378ee6a1217ade08c3d7c82d6fd1f5340debe92 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 12:43:11 +0200 Subject: [PATCH 11/17] Re-order to match stat struct --- src/lib/libsyscall.js | 2 +- src/lib/libwasmfs.js | 4 ++-- .../test_codesize_file_preload.expected.js | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/lib/libsyscall.js b/src/lib/libsyscall.js index ed39f4f64d14c..25aaf65ee5fe1 100644 --- a/src/lib/libsyscall.js +++ b/src/lib/libsyscall.js @@ -48,6 +48,7 @@ var SyscallsLibrary = { {{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i64') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_blocks, 'stat.blocks', 'i32') }}}; + {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i64') }}}; var atime = stat.atime.getTime(); var mtime = stat.mtime.getTime(); var ctime = stat.ctime.getTime(); @@ -57,7 +58,6 @@ var SyscallsLibrary = { {{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '(mtime % 1000) * 1000 * 1000', SIZE_TYPE) }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(ctime / 1000)', 'i64') }}}; {{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '(ctime % 1000) * 1000 * 1000', SIZE_TYPE) }}}; - {{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i64') }}}; return 0; }, writeStatFs(buf, stats) { diff --git a/src/lib/libwasmfs.js b/src/lib/libwasmfs.js index 5a4f29ede10c3..8ffaba674dd65 100644 --- a/src/lib/libwasmfs.js +++ b/src/lib/libwasmfs.js @@ -260,10 +260,10 @@ addToLibrary({ size: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_size, "i53") }}}, blksize: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_blksize, "i32") }}}, blocks: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_blocks, "i32") }}}, + ino: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_ino, "u53") }}}, atime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_atim.tv_sec, "i53") }}}, mtime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_mtim.tv_sec, "i53") }}}, - ctime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_ctim.tv_sec, "i53") }}}, - ino: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_ino, "u53") }}} + ctime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_ctim.tv_sec, "i53") }}} } }, stat(path) { diff --git a/test/codesize/test_codesize_file_preload.expected.js b/test/codesize/test_codesize_file_preload.expected.js index 7921688f01882..2b263f80bb312 100644 --- a/test/codesize/test_codesize_file_preload.expected.js +++ b/test/codesize/test_codesize_file_preload.expected.js @@ -3028,16 +3028,16 @@ var SYSCALLS = { HEAP64[(((buf) + (24)) >> 3)] = BigInt(stat.size); HEAP32[(((buf) + (32)) >> 2)] = 4096; HEAP32[(((buf) + (36)) >> 2)] = stat.blocks; + HEAP64[(((buf) + (40)) >> 3)] = BigInt(stat.ino); var atime = stat.atime.getTime(); var mtime = stat.mtime.getTime(); var ctime = stat.ctime.getTime(); - HEAP64[(((buf) + (40)) >> 3)] = BigInt(Math.floor(atime / 1e3)); - HEAPU32[(((buf) + (48)) >> 2)] = (atime % 1e3) * 1e3 * 1e3; - HEAP64[(((buf) + (56)) >> 3)] = BigInt(Math.floor(mtime / 1e3)); - HEAPU32[(((buf) + (64)) >> 2)] = (mtime % 1e3) * 1e3 * 1e3; - HEAP64[(((buf) + (72)) >> 3)] = BigInt(Math.floor(ctime / 1e3)); - HEAPU32[(((buf) + (80)) >> 2)] = (ctime % 1e3) * 1e3 * 1e3; - HEAP64[(((buf) + (88)) >> 3)] = BigInt(stat.ino); + HEAP64[(((buf) + (48)) >> 3)] = BigInt(Math.floor(atime / 1e3)); + HEAPU32[(((buf) + (56)) >> 2)] = (atime % 1e3) * 1e3 * 1e3; + HEAP64[(((buf) + (64)) >> 3)] = BigInt(Math.floor(mtime / 1e3)); + HEAPU32[(((buf) + (72)) >> 2)] = (mtime % 1e3) * 1e3 * 1e3; + HEAP64[(((buf) + (80)) >> 3)] = BigInt(Math.floor(ctime / 1e3)); + HEAPU32[(((buf) + (88)) >> 2)] = (ctime % 1e3) * 1e3 * 1e3; return 0; }, writeStatFs(buf, stats) { From 6d50b1c39c3ee1a5c671b46136abadb4c06b304e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 13:00:50 +0200 Subject: [PATCH 12/17] Update `system_libs.py` after musl v1.2.6 See: https://git.musl-libc.org/cgit/musl/commit/?id=ef7d0ae21240eac9fc1e8088112bfb0fac507578 --- tools/system_libs.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/system_libs.py b/tools/system_libs.py index f2ac962c8f444..8f83a8052f21d 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -1362,6 +1362,7 @@ def get_files(self): '__map_file.c', 'strftime.c', '__tz.c', + '__utc.c', '__tm_to_secs.c', '__year_to_secs.c', '__month_to_secs.c', @@ -2304,6 +2305,7 @@ def get_files(self): path='system/lib/libc/musl/src/time', filenames=['__secs_to_tm.c', '__tz.c', + '__utc.c', 'gettimeofday.c', 'localtime_r.c', 'gmtime_r.c', From 3d7b8f3f02698f196b29032dcf35e9ac2e907de1 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 13:18:35 +0200 Subject: [PATCH 13/17] Fix `other.test_standalone_whole_archive` failure Details: ``` wasm-ld: error: --shared-memory is disallowed by exit.o because it was not compiled with 'atomics' or 'bulk-memory' features. ``` --- system/lib/libc/musl/src/exit/exit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/lib/libc/musl/src/exit/exit.c b/system/lib/libc/musl/src/exit/exit.c index 17b33cc61716c..1637fdaae0b5a 100644 --- a/system/lib/libc/musl/src/exit/exit.c +++ b/system/lib/libc/musl/src/exit/exit.c @@ -29,6 +29,7 @@ weak_alias(libc_exit_fini, __libc_exit_fini); _Noreturn void exit(int code) { +#ifdef _REENTRANT // XXX Emscripten: guard with _REENTRANT /* Handle potentially concurrent or recursive calls to exit, * whose behaviors have traditionally been undefined by the * standards. Using a custom lock here avoids pulling in lock @@ -39,6 +40,7 @@ _Noreturn void exit(int code) int prev = a_cas(exit_lock, 0, tid); if (prev == tid) a_crash(); else if (prev) for (;;) __sys_pause(); +#endif __funcs_on_exit(); __libc_exit_fini(); From 7d0afe699c6c99d72ae348ce2853ad996599d799 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 May 2026 11:20:36 +0000 Subject: [PATCH 14/17] Automatic rebaseline of codesize expectations. NFC This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (25) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_ctors1.json: 151887 => 151940 [+53 bytes / +0.03%] codesize/test_codesize_cxx_ctors2.json: 151292 => 151346 [+54 bytes / +0.04%] codesize/test_codesize_cxx_except.json: 195766 => 195851 [+85 bytes / +0.04%] codesize/test_codesize_cxx_except_wasm.json: 167018 => 167109 [+91 bytes / +0.05%] codesize/test_codesize_cxx_except_wasm_legacy.json: 164898 => 164989 [+91 bytes / +0.06%] codesize/test_codesize_cxx_lto.json: 120587 => 120608 [+21 bytes / +0.02%] codesize/test_codesize_cxx_mangle.json: 262245 => 262330 [+85 bytes / +0.03%] codesize/test_codesize_cxx_noexcept.json: 153917 => 153956 [+39 bytes / +0.03%] codesize/test_codesize_cxx_wasmfs.json: 179773 => 179812 [+39 bytes / +0.02%] codesize/test_codesize_file_preload.json: 23855 => 23873 [+18 bytes / +0.08%] codesize/test_codesize_hello_O0.json: 39070 => 39335 [+265 bytes / +0.68%] codesize/test_codesize_hello_O1.json: 8875 => 8889 [+14 bytes / +0.16%] codesize/test_codesize_hello_O2.json: 6221 => 6235 [+14 bytes / +0.23%] codesize/test_codesize_hello_O3.json: 5913 => 5931 [+18 bytes / +0.30%] codesize/test_codesize_hello_Os.json: 5903 => 5919 [+16 bytes / +0.27%] codesize/test_codesize_hello_Oz.json: 5072 => 5088 [+16 bytes / +0.32%] codesize/test_codesize_hello_dylink.json: 43922 => 44112 [+190 bytes / +0.43%] codesize/test_codesize_hello_dylink_all.json: 822610 => 822562 [-48 bytes / -0.01%] codesize/test_codesize_hello_single_file.json: 5223 => 5241 [+18 bytes / +0.34%] codesize/test_codesize_hello_wasmfs.json: 5913 => 5931 [+18 bytes / +0.30%] codesize/test_codesize_minimal_pthreads.json: 26370 => 26347 [-23 bytes / -0.09%] codesize/test_codesize_minimal_pthreads_memgrowth.json: 26774 => 26751 [-23 bytes / -0.09%] codesize/test_minimal_runtime_code_size_random_printf_wasm.json: 10815 => 11057 [+242 bytes / +2.24%] codesize/test_minimal_runtime_code_size_random_printf_wasm2js.json: 17114 => 17417 [+303 bytes / +1.77%] codesize/test_unoptimized_code_size.json: 180144 => 180893 [+749 bytes / +0.42%] Average change: +0.31% (-0.09% - +2.24%) ``` --- test/codesize/test_codesize_cxx_ctors1.json | 8 ++++---- test/codesize/test_codesize_cxx_ctors2.json | 8 ++++---- test/codesize/test_codesize_cxx_except.json | 8 ++++---- test/codesize/test_codesize_cxx_except_wasm.json | 8 ++++---- .../test_codesize_cxx_except_wasm_legacy.json | 8 ++++---- test/codesize/test_codesize_cxx_lto.json | 8 ++++---- test/codesize/test_codesize_cxx_mangle.json | 8 ++++---- test/codesize/test_codesize_cxx_noexcept.json | 8 ++++---- test/codesize/test_codesize_cxx_wasmfs.json | 8 ++++---- test/codesize/test_codesize_file_preload.json | 8 ++++---- test/codesize/test_codesize_hello_O0.json | 9 +++++---- test/codesize/test_codesize_hello_O1.json | 8 ++++---- test/codesize/test_codesize_hello_O2.json | 8 ++++---- test/codesize/test_codesize_hello_O3.json | 8 ++++---- test/codesize/test_codesize_hello_Os.json | 8 ++++---- test/codesize/test_codesize_hello_Oz.json | 8 ++++---- test/codesize/test_codesize_hello_dylink.json | 8 ++++---- .../codesize/test_codesize_hello_dylink_all.json | 8 ++++++-- .../test_codesize_hello_single_file.json | 4 ++-- test/codesize/test_codesize_hello_wasmfs.json | 8 ++++---- .../codesize/test_codesize_minimal_pthreads.json | 8 ++++---- ...test_codesize_minimal_pthreads_memgrowth.json | 8 ++++---- ...mal_runtime_code_size_random_printf_wasm.json | 4 ++-- ..._runtime_code_size_random_printf_wasm2js.json | 4 ++-- test/codesize/test_unoptimized_code_size.json | 16 ++++++++-------- 25 files changed, 101 insertions(+), 96 deletions(-) diff --git a/test/codesize/test_codesize_cxx_ctors1.json b/test/codesize/test_codesize_cxx_ctors1.json index 2c79cb1867c54..573557ccf688e 100644 --- a/test/codesize/test_codesize_cxx_ctors1.json +++ b/test/codesize/test_codesize_cxx_ctors1.json @@ -1,10 +1,10 @@ { "a.out.js": 19260, "a.out.js.gz": 7991, - "a.out.nodebug.wasm": 132627, - "a.out.nodebug.wasm.gz": 49921, - "total": 151887, - "total_gz": 57912, + "a.out.nodebug.wasm": 132680, + "a.out.nodebug.wasm.gz": 49972, + "total": 151940, + "total_gz": 57963, "sent": [ "__cxa_throw", "_abort_js", diff --git a/test/codesize/test_codesize_cxx_ctors2.json b/test/codesize/test_codesize_cxx_ctors2.json index 804f183eeb82f..a91d5516b555e 100644 --- a/test/codesize/test_codesize_cxx_ctors2.json +++ b/test/codesize/test_codesize_cxx_ctors2.json @@ -1,10 +1,10 @@ { "a.out.js": 19237, "a.out.js.gz": 7978, - "a.out.nodebug.wasm": 132055, - "a.out.nodebug.wasm.gz": 49575, - "total": 151292, - "total_gz": 57553, + "a.out.nodebug.wasm": 132109, + "a.out.nodebug.wasm.gz": 49634, + "total": 151346, + "total_gz": 57612, "sent": [ "__cxa_throw", "_abort_js", diff --git a/test/codesize/test_codesize_cxx_except.json b/test/codesize/test_codesize_cxx_except.json index 4117b5c4453c8..97bf4c31259d4 100644 --- a/test/codesize/test_codesize_cxx_except.json +++ b/test/codesize/test_codesize_cxx_except.json @@ -1,10 +1,10 @@ { "a.out.js": 23240, "a.out.js.gz": 8977, - "a.out.nodebug.wasm": 172526, - "a.out.nodebug.wasm.gz": 57447, - "total": 195766, - "total_gz": 66424, + "a.out.nodebug.wasm": 172611, + "a.out.nodebug.wasm.gz": 57524, + "total": 195851, + "total_gz": 66501, "sent": [ "__cxa_begin_catch", "__cxa_end_catch", diff --git a/test/codesize/test_codesize_cxx_except_wasm.json b/test/codesize/test_codesize_cxx_except_wasm.json index 69dbaf45c33db..bc5c31364bd50 100644 --- a/test/codesize/test_codesize_cxx_except_wasm.json +++ b/test/codesize/test_codesize_cxx_except_wasm.json @@ -1,10 +1,10 @@ { "a.out.js": 19092, "a.out.js.gz": 7925, - "a.out.nodebug.wasm": 147926, - "a.out.nodebug.wasm.gz": 55309, - "total": 167018, - "total_gz": 63234, + "a.out.nodebug.wasm": 148017, + "a.out.nodebug.wasm.gz": 55360, + "total": 167109, + "total_gz": 63285, "sent": [ "_abort_js", "_tzset_js", diff --git a/test/codesize/test_codesize_cxx_except_wasm_legacy.json b/test/codesize/test_codesize_cxx_except_wasm_legacy.json index 00312e3edb1e2..6eeac72a1326d 100644 --- a/test/codesize/test_codesize_cxx_except_wasm_legacy.json +++ b/test/codesize/test_codesize_cxx_except_wasm_legacy.json @@ -1,10 +1,10 @@ { "a.out.js": 19166, "a.out.js.gz": 7949, - "a.out.nodebug.wasm": 145732, - "a.out.nodebug.wasm.gz": 54936, - "total": 164898, - "total_gz": 62885, + "a.out.nodebug.wasm": 145823, + "a.out.nodebug.wasm.gz": 54993, + "total": 164989, + "total_gz": 62942, "sent": [ "_abort_js", "_tzset_js", diff --git a/test/codesize/test_codesize_cxx_lto.json b/test/codesize/test_codesize_cxx_lto.json index b5022eec5a4d8..c54154d602a42 100644 --- a/test/codesize/test_codesize_cxx_lto.json +++ b/test/codesize/test_codesize_cxx_lto.json @@ -1,10 +1,10 @@ { "a.out.js": 18629, "a.out.js.gz": 7684, - "a.out.nodebug.wasm": 101958, - "a.out.nodebug.wasm.gz": 39461, - "total": 120587, - "total_gz": 47145, + "a.out.nodebug.wasm": 101979, + "a.out.nodebug.wasm.gz": 39479, + "total": 120608, + "total_gz": 47163, "sent": [ "a (emscripten_resize_heap)", "b (_setitimer_js)", diff --git a/test/codesize/test_codesize_cxx_mangle.json b/test/codesize/test_codesize_cxx_mangle.json index e307614b293c0..7e7d9caee26e3 100644 --- a/test/codesize/test_codesize_cxx_mangle.json +++ b/test/codesize/test_codesize_cxx_mangle.json @@ -1,10 +1,10 @@ { "a.out.js": 23290, "a.out.js.gz": 8999, - "a.out.nodebug.wasm": 238955, - "a.out.nodebug.wasm.gz": 79818, - "total": 262245, - "total_gz": 88817, + "a.out.nodebug.wasm": 239040, + "a.out.nodebug.wasm.gz": 79876, + "total": 262330, + "total_gz": 88875, "sent": [ "__cxa_begin_catch", "__cxa_end_catch", diff --git a/test/codesize/test_codesize_cxx_noexcept.json b/test/codesize/test_codesize_cxx_noexcept.json index 32250f8e3793b..f991907c790c3 100644 --- a/test/codesize/test_codesize_cxx_noexcept.json +++ b/test/codesize/test_codesize_cxx_noexcept.json @@ -1,10 +1,10 @@ { "a.out.js": 19260, "a.out.js.gz": 7991, - "a.out.nodebug.wasm": 134657, - "a.out.nodebug.wasm.gz": 50769, - "total": 153917, - "total_gz": 58760, + "a.out.nodebug.wasm": 134696, + "a.out.nodebug.wasm.gz": 50824, + "total": 153956, + "total_gz": 58815, "sent": [ "__cxa_throw", "_abort_js", diff --git a/test/codesize/test_codesize_cxx_wasmfs.json b/test/codesize/test_codesize_cxx_wasmfs.json index 7f6c324000085..351bfa981be4e 100644 --- a/test/codesize/test_codesize_cxx_wasmfs.json +++ b/test/codesize/test_codesize_cxx_wasmfs.json @@ -1,10 +1,10 @@ { "a.out.js": 7023, "a.out.js.gz": 3310, - "a.out.nodebug.wasm": 172750, - "a.out.nodebug.wasm.gz": 63325, - "total": 179773, - "total_gz": 66635, + "a.out.nodebug.wasm": 172789, + "a.out.nodebug.wasm.gz": 63376, + "total": 179812, + "total_gz": 66686, "sent": [ "__cxa_throw", "_abort_js", diff --git a/test/codesize/test_codesize_file_preload.json b/test/codesize/test_codesize_file_preload.json index 45bd9ba83ff03..bfbe3e7e9a2cd 100644 --- a/test/codesize/test_codesize_file_preload.json +++ b/test/codesize/test_codesize_file_preload.json @@ -1,10 +1,10 @@ { "a.out.js": 22207, "a.out.js.gz": 9203, - "a.out.nodebug.wasm": 1648, - "a.out.nodebug.wasm.gz": 938, - "total": 23855, - "total_gz": 10141, + "a.out.nodebug.wasm": 1666, + "a.out.nodebug.wasm.gz": 945, + "total": 23873, + "total_gz": 10148, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_O0.json b/test/codesize/test_codesize_hello_O0.json index 978d779d3bcd0..0ff577f24f2ac 100644 --- a/test/codesize/test_codesize_hello_O0.json +++ b/test/codesize/test_codesize_hello_O0.json @@ -1,10 +1,10 @@ { "a.out.js": 24220, "a.out.js.gz": 8713, - "a.out.nodebug.wasm": 14850, - "a.out.nodebug.wasm.gz": 7314, - "total": 39070, - "total_gz": 16027, + "a.out.nodebug.wasm": 15115, + "a.out.nodebug.wasm.gz": 7464, + "total": 39335, + "total_gz": 16177, "sent": [ "fd_write" ], @@ -71,6 +71,7 @@ "$pop_arg_long_double", "$printf", "$printf_core", + "$scalbn", "$strerror", "$strnlen", "$vfprintf", diff --git a/test/codesize/test_codesize_hello_O1.json b/test/codesize/test_codesize_hello_O1.json index 1cee141c63fce..02ca2dad0ba4f 100644 --- a/test/codesize/test_codesize_hello_O1.json +++ b/test/codesize/test_codesize_hello_O1.json @@ -1,10 +1,10 @@ { "a.out.js": 6345, "a.out.js.gz": 2456, - "a.out.nodebug.wasm": 2530, - "a.out.nodebug.wasm.gz": 1421, - "total": 8875, - "total_gz": 3877, + "a.out.nodebug.wasm": 2544, + "a.out.nodebug.wasm.gz": 1436, + "total": 8889, + "total_gz": 3892, "sent": [ "fd_write" ], diff --git a/test/codesize/test_codesize_hello_O2.json b/test/codesize/test_codesize_hello_O2.json index 383ae20cdc135..7a49e2f53ac7e 100644 --- a/test/codesize/test_codesize_hello_O2.json +++ b/test/codesize/test_codesize_hello_O2.json @@ -1,10 +1,10 @@ { "a.out.js": 4323, "a.out.js.gz": 2130, - "a.out.nodebug.wasm": 1898, - "a.out.nodebug.wasm.gz": 1120, - "total": 6221, - "total_gz": 3250, + "a.out.nodebug.wasm": 1912, + "a.out.nodebug.wasm.gz": 1129, + "total": 6235, + "total_gz": 3259, "sent": [ "fd_write" ], diff --git a/test/codesize/test_codesize_hello_O3.json b/test/codesize/test_codesize_hello_O3.json index c6cc2db3c5d91..4c64aa01850f3 100644 --- a/test/codesize/test_codesize_hello_O3.json +++ b/test/codesize/test_codesize_hello_O3.json @@ -1,10 +1,10 @@ { "a.out.js": 4265, "a.out.js.gz": 2089, - "a.out.nodebug.wasm": 1648, - "a.out.nodebug.wasm.gz": 938, - "total": 5913, - "total_gz": 3027, + "a.out.nodebug.wasm": 1666, + "a.out.nodebug.wasm.gz": 945, + "total": 5931, + "total_gz": 3034, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_Os.json b/test/codesize/test_codesize_hello_Os.json index 433d6af14da02..552851389c2b6 100644 --- a/test/codesize/test_codesize_hello_Os.json +++ b/test/codesize/test_codesize_hello_Os.json @@ -1,10 +1,10 @@ { "a.out.js": 4265, "a.out.js.gz": 2089, - "a.out.nodebug.wasm": 1638, - "a.out.nodebug.wasm.gz": 941, - "total": 5903, - "total_gz": 3030, + "a.out.nodebug.wasm": 1654, + "a.out.nodebug.wasm.gz": 953, + "total": 5919, + "total_gz": 3042, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_Oz.json b/test/codesize/test_codesize_hello_Oz.json index a25237d4dd55b..ace0d3116f3d6 100644 --- a/test/codesize/test_codesize_hello_Oz.json +++ b/test/codesize/test_codesize_hello_Oz.json @@ -1,10 +1,10 @@ { "a.out.js": 3900, "a.out.js.gz": 1896, - "a.out.nodebug.wasm": 1172, - "a.out.nodebug.wasm.gz": 723, - "total": 5072, - "total_gz": 2619, + "a.out.nodebug.wasm": 1188, + "a.out.nodebug.wasm.gz": 731, + "total": 5088, + "total_gz": 2627, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_hello_dylink.json b/test/codesize/test_codesize_hello_dylink.json index 2706ec79a2273..37371870e2c76 100644 --- a/test/codesize/test_codesize_hello_dylink.json +++ b/test/codesize/test_codesize_hello_dylink.json @@ -1,10 +1,10 @@ { "a.out.js": 26251, "a.out.js.gz": 11194, - "a.out.nodebug.wasm": 17671, - "a.out.nodebug.wasm.gz": 8925, - "total": 43922, - "total_gz": 20119, + "a.out.nodebug.wasm": 17861, + "a.out.nodebug.wasm.gz": 9021, + "total": 44112, + "total_gz": 20215, "sent": [ "__syscall_stat64", "emscripten_resize_heap", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 9ab953cf7ee21..2de4f42364796 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { "a.out.js": 244573, - "a.out.nodebug.wasm": 578037, - "total": 822610, + "a.out.nodebug.wasm": 577989, + "total": 822562, "sent": [ "IMG_Init", "IMG_Load", @@ -2795,6 +2795,7 @@ "posix_close", "posix_fadvise", "posix_fallocate", + "posix_getdents", "posix_madvise", "posix_memalign", "posix_openpt", @@ -3940,10 +3941,12 @@ "$cexp", "$cexpf", "$cexpl", + "$cfgetispeed", "$cfgetospeed", "$cfmakeraw", "$cfsetispeed", "$cfsetospeed", + "$cfsetspeed", "$chdir", "$checkint", "$checkint", @@ -4568,6 +4571,7 @@ "$posix_close", "$posix_fadvise", "$posix_fallocate", + "$posix_getdents", "$posix_openpt", "$posix_spawn", "$posix_spawn_file_actions_addchdir_np", diff --git a/test/codesize/test_codesize_hello_single_file.json b/test/codesize/test_codesize_hello_single_file.json index efdca993df465..6fac8a3d66292 100644 --- a/test/codesize/test_codesize_hello_single_file.json +++ b/test/codesize/test_codesize_hello_single_file.json @@ -1,6 +1,6 @@ { - "a.out.js": 5223, - "a.out.js.gz": 2887, + "a.out.js": 5241, + "a.out.js.gz": 2893, "sent": [ "a (fd_write)" ] diff --git a/test/codesize/test_codesize_hello_wasmfs.json b/test/codesize/test_codesize_hello_wasmfs.json index c6cc2db3c5d91..4c64aa01850f3 100644 --- a/test/codesize/test_codesize_hello_wasmfs.json +++ b/test/codesize/test_codesize_hello_wasmfs.json @@ -1,10 +1,10 @@ { "a.out.js": 4265, "a.out.js.gz": 2089, - "a.out.nodebug.wasm": 1648, - "a.out.nodebug.wasm.gz": 938, - "total": 5913, - "total_gz": 3027, + "a.out.nodebug.wasm": 1666, + "a.out.nodebug.wasm.gz": 945, + "total": 5931, + "total_gz": 3034, "sent": [ "a (fd_write)" ], diff --git a/test/codesize/test_codesize_minimal_pthreads.json b/test/codesize/test_codesize_minimal_pthreads.json index 73c3e5be27176..0946121a4b1f8 100644 --- a/test/codesize/test_codesize_minimal_pthreads.json +++ b/test/codesize/test_codesize_minimal_pthreads.json @@ -1,10 +1,10 @@ { "a.out.js": 7323, "a.out.js.gz": 3573, - "a.out.nodebug.wasm": 19047, - "a.out.nodebug.wasm.gz": 8794, - "total": 26370, - "total_gz": 12367, + "a.out.nodebug.wasm": 19024, + "a.out.nodebug.wasm.gz": 8776, + "total": 26347, + "total_gz": 12349, "sent": [ "a (memory)", "b (exit)", diff --git a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json index 84a54460ee792..97f18ee6e6830 100644 --- a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json +++ b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json @@ -1,10 +1,10 @@ { "a.out.js": 7726, "a.out.js.gz": 3779, - "a.out.nodebug.wasm": 19048, - "a.out.nodebug.wasm.gz": 8796, - "total": 26774, - "total_gz": 12575, + "a.out.nodebug.wasm": 19025, + "a.out.nodebug.wasm.gz": 8777, + "total": 26751, + "total_gz": 12556, "sent": [ "a (memory)", "b (exit)", diff --git a/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json b/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json index 2d6f52c4ad1e9..58825a46c4c30 100644 --- a/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json +++ b/test/codesize/test_minimal_runtime_code_size_random_printf_wasm.json @@ -1,4 +1,4 @@ { - "a.html": 10815, - "a.html.gz": 5649 + "a.html": 11057, + "a.html.gz": 5755 } diff --git a/test/codesize/test_minimal_runtime_code_size_random_printf_wasm2js.json b/test/codesize/test_minimal_runtime_code_size_random_printf_wasm2js.json index abb290e68d76b..6597f80fe7fa6 100644 --- a/test/codesize/test_minimal_runtime_code_size_random_printf_wasm2js.json +++ b/test/codesize/test_minimal_runtime_code_size_random_printf_wasm2js.json @@ -1,4 +1,4 @@ { - "a.html": 17114, - "a.html.gz": 7478 + "a.html": 17417, + "a.html.gz": 7657 } diff --git a/test/codesize/test_unoptimized_code_size.json b/test/codesize/test_unoptimized_code_size.json index 2bac6e12355a6..70c82fa5b54de 100644 --- a/test/codesize/test_unoptimized_code_size.json +++ b/test/codesize/test_unoptimized_code_size.json @@ -1,16 +1,16 @@ { "hello_world.js": 56997, "hello_world.js.gz": 17742, - "hello_world.wasm": 14850, - "hello_world.wasm.gz": 7314, + "hello_world.wasm": 15115, + "hello_world.wasm.gz": 7464, "no_asserts.js": 26622, "no_asserts.js.gz": 8888, - "no_asserts.wasm": 12010, - "no_asserts.wasm.gz": 5880, + "no_asserts.wasm": 12229, + "no_asserts.wasm.gz": 6004, "strict.js": 54815, "strict.js.gz": 17049, - "strict.wasm": 14850, - "strict.wasm.gz": 7310, - "total": 180144, - "total_gz": 64183 + "strict.wasm": 15115, + "strict.wasm.gz": 7457, + "total": 180893, + "total_gz": 64604 } From 1f05268c99c04985a375e319516ff538eb90b294 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 6 May 2026 16:46:15 +0200 Subject: [PATCH 15/17] Revert "Revise Emscripten-specific include changes" This reverts commit 2bd5f4560d2ad4f093e8e50a6a53a0fa4700eaad. --- system/lib/libc/musl/include/unistd.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/system/lib/libc/musl/include/unistd.h b/system/lib/libc/musl/include/unistd.h index 539cd7c1c9b0e..59b38fd01d8a0 100644 --- a/system/lib/libc/musl/include/unistd.h +++ b/system/lib/libc/musl/include/unistd.h @@ -240,20 +240,20 @@ pid_t gettid(void); #define _POSIX_NO_TRUNC 1 #define _POSIX_RAW_SOCKETS _POSIX_VERSION -#ifdef __EMSCRIPTEN__ -#define _POSIX_REALTIME_SIGNALS -1 -#else +#ifndef __EMSCRIPTEN__ #define _POSIX_REALTIME_SIGNALS _POSIX_VERSION +#else +#define _POSIX_REALTIME_SIGNALS -1 #endif #define _POSIX_REGEXP 1 #define _POSIX_SAVED_IDS 1 #define _POSIX_SHELL 1 -#ifdef __EMSCRIPTEN__ -#define _POSIX_SPAWN -1 -#else +#ifndef __EMSCRIPTEN__ #define _POSIX_SPAWN _POSIX_VERSION +#else +#define _POSIX_SPAWN -1 #endif #define _POSIX_VDISABLE 0 @@ -263,10 +263,10 @@ pid_t gettid(void); #else #define _POSIX_THREADS _POSIX_VERSION #endif -#ifdef __EMSCRIPTEN__ -#define _POSIX_THREAD_PROCESS_SHARED -1 -#else +#ifndef __EMSCRIPTEN__ #define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION +#else +#define _POSIX_THREAD_PROCESS_SHARED -1 #endif #define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION #define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION From a499fc2342963586df97c83c0cfb091200f731a4 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 6 May 2026 16:46:17 +0200 Subject: [PATCH 16/17] Revert "Revise Emscripten-specific changes" This partially reverts commit 82cc2d33bf5713c6a960ca0b0613f36c9a76509a. --- system/lib/libc/musl/include/setjmp.h | 2 +- system/lib/libc/musl/src/exit/abort.c | 4 +- system/lib/libc/musl/src/internal/libm.h | 17 +++---- .../lib/libc/musl/src/internal/locale_impl.h | 2 +- .../lib/libc/musl/src/internal/pthread_impl.h | 2 +- system/lib/libc/musl/src/internal/syscall.h | 51 ++++++++++--------- system/lib/libc/musl/src/linux/sbrk.c | 3 +- system/lib/libc/musl/src/math/sqrt.c | 2 +- system/lib/libc/musl/src/math/sqrtf.c | 2 +- .../lib/libc/musl/src/network/freeaddrinfo.c | 2 +- system/lib/libc/musl/src/sched/sched_yield.c | 4 +- system/lib/libc/musl/src/stat/fchmod.c | 2 +- system/lib/libc/musl/src/stat/fstatat.c | 2 +- system/lib/libc/musl/src/stdio/__stdio_read.c | 3 +- .../lib/libc/musl/src/stdio/__stdio_write.c | 2 +- system/lib/libc/musl/src/stdio/stdout.c | 4 +- system/lib/libc/musl/src/stdio/vfprintf.c | 2 +- system/lib/libc/musl/src/string/memcmp.c | 2 +- system/lib/libc/musl/src/thread/__timedwait.c | 4 +- .../musl/src/thread/pthread_mutex_timedlock.c | 2 +- system/lib/libc/musl/src/time/clock_gettime.c | 2 +- .../lib/libc/musl/src/time/clock_nanosleep.c | 4 +- system/lib/libc/musl/src/time/clock_settime.c | 7 ++- system/lib/libc/musl/src/unistd/fchdir.c | 2 +- system/lib/libc/musl/src/unistd/fchown.c | 4 +- system/lib/libc/musl/src/unistd/fsync.c | 2 +- system/lib/libc/musl/src/unistd/pread.c | 2 +- system/lib/libc/musl/src/unistd/preadv.c | 2 +- system/lib/libc/musl/src/unistd/pwrite.c | 2 +- system/lib/libc/musl/src/unistd/pwritev.c | 2 +- system/lib/libc/musl/src/unistd/read.c | 2 +- system/lib/libc/musl/src/unistd/readv.c | 2 +- system/lib/libc/musl/src/unistd/write.c | 2 +- system/lib/libc/musl/src/unistd/writev.c | 4 +- 34 files changed, 78 insertions(+), 75 deletions(-) diff --git a/system/lib/libc/musl/include/setjmp.h b/system/lib/libc/musl/include/setjmp.h index 5aabfa95c4a05..af72c80cdbce0 100644 --- a/system/lib/libc/musl/include/setjmp.h +++ b/system/lib/libc/musl/include/setjmp.h @@ -26,7 +26,7 @@ typedef struct __jmp_buf_tag { || defined(_BSD_SOURCE) typedef jmp_buf sigjmp_buf; /* XXX EMSCRIPTEN: No signals support, alias sigsetjmp and siglongjmp to their non-signals counterparts. */ -#if defined(__EMSCRIPTEN__) && !defined(LLVM_LIBC) +#if __EMSCRIPTEN__ && !defined(LLVM_LIBC) #define sigsetjmp(buf, x) setjmp((buf)) #define siglongjmp(buf, val) longjmp(buf, val) #else diff --git a/system/lib/libc/musl/src/exit/abort.c b/system/lib/libc/musl/src/exit/abort.c index 8ff8a8626ee07..a6427d51d66e9 100644 --- a/system/lib/libc/musl/src/exit/abort.c +++ b/system/lib/libc/musl/src/exit/abort.c @@ -6,13 +6,13 @@ #include "lock.h" #include "ksigaction.h" -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ #include "emscripten_internal.h" #endif _Noreturn void abort(void) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ /* In emscripten we call out to JS to perform the actual abort where it can * produce a nice error. * Note that the JS library function is not called `abort` to avoid conflict diff --git a/system/lib/libc/musl/src/internal/libm.h b/system/lib/libc/musl/src/internal/libm.h index 9d8b892d5b3e8..a47208aa6ad3c 100644 --- a/system/lib/libc/musl/src/internal/libm.h +++ b/system/lib/libc/musl/src/internal/libm.h @@ -144,16 +144,6 @@ static inline long double fp_barrierl(long double x) } #endif -#ifdef __EMSCRIPTEN__ -/* - * wasm doesn't have user-accessible floating point exceptions, so there's - * no point in trying to force expression evaluations to produce them. - */ -#define fp_force_evalf(x) -#define fp_force_eval(x) -#define fp_force_evall(x) -#define FORCE_EVAL(x) -#else /* fp_force_eval ensures that the input value is computed when that's otherwise unused. To prevent the constant folding of the input expression, an additional fp_barrier may be needed or a compilation @@ -187,6 +177,13 @@ static inline void fp_force_evall(long double x) } #endif +#ifdef __EMSCRIPTEN__ +/* + * asm.js doesn't have user-accessible floating point exceptions, so there's + * no point in trying to force expression evaluations to produce them. + */ +#define FORCE_EVAL(x) +#else #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ fp_force_evalf(x); \ diff --git a/system/lib/libc/musl/src/internal/locale_impl.h b/system/lib/libc/musl/src/internal/locale_impl.h index 1f46f88fa7d74..9a7b07c4aac0e 100644 --- a/system/lib/libc/musl/src/internal/locale_impl.h +++ b/system/lib/libc/musl/src/internal/locale_impl.h @@ -31,7 +31,7 @@ hidden char *__gettextdomain(void); #define LOC_MAP_FAILED ((const struct __locale_map *)-1) -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ // Disable message translation completely under emscripten since we don't // support loading any actual locale data, and even looking up the current // local via CURRENT_LOCALE via TLS is not free. diff --git a/system/lib/libc/musl/src/internal/pthread_impl.h b/system/lib/libc/musl/src/internal/pthread_impl.h index d7978ba8fccf7..a366b6cef8eb3 100644 --- a/system/lib/libc/musl/src/internal/pthread_impl.h +++ b/system/lib/libc/musl/src/internal/pthread_impl.h @@ -237,7 +237,7 @@ static inline void __wake(volatile void *addr, int cnt, int priv) if (priv) priv = FUTEX_PRIVATE; if (cnt<0) cnt = INT_MAX; #ifdef __EMSCRIPTEN__ - emscripten_futex_wake(addr, cnt); + emscripten_futex_wake(addr, (cnt)<0?INT_MAX:(cnt)); #else __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); diff --git a/system/lib/libc/musl/src/internal/syscall.h b/system/lib/libc/musl/src/internal/syscall.h index 22fc5f146c8b5..4476dbe7db09a 100644 --- a/system/lib/libc/musl/src/internal/syscall.h +++ b/system/lib/libc/musl/src/internal/syscall.h @@ -30,7 +30,7 @@ typedef long syscall_arg_t; #endif -#ifdef __cplusplus // XXX Emscripten we need C linkage for this +#ifdef __cplusplus extern "C" { #endif hidden long __syscall_ret(unsigned long), @@ -40,7 +40,14 @@ hidden long __syscall_ret(unsigned long), } #endif -#ifdef __EMSCRIPTEN__ +#ifndef __EMSCRIPTEN__ +#define __syscall1(n,a) __syscall1(n,__scc(a)) +#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) +#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) +#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) +#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) +#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) +#else // __EMSCRIPTEN__ #define __syscall_emscripten(n, ...) n(__VA_ARGS__) #define __syscall_emscripten0(n) __syscall_emscripten(n) #define __syscall_emscripten1(n,a) __syscall_emscripten(n,__scc(a)) @@ -49,14 +56,7 @@ hidden long __syscall_ret(unsigned long), #define __syscall_emscripten4(n,a,b,c,d) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d)) #define __syscall_emscripten5(n,a,b,c,d,e) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) #define __syscall_emscripten6(n,a,b,c,d,e,f) __syscall_emscripten(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#else // !defined(__EMSCRIPTEN__) -#define __syscall1(n,a) __syscall1(n,__scc(a)) -#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) -#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) -#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) -#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) -#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) -#endif // !defined(__EMSCRIPTEN__) +#endif // __EMSCRIPTEN__ #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,) @@ -64,10 +64,10 @@ hidden long __syscall_ret(unsigned long), #define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b) #define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) -#ifdef __EMSCRIPTEN__ -#define __syscall(...) __SYSCALL_DISP(__syscall_emscripten,__VA_ARGS__) -#else +#ifndef __EMSCRIPTEN__ #define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) +#else +#define __syscall(...) __SYSCALL_DISP(__syscall_emscripten,__VA_ARGS__) #endif #define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) @@ -75,9 +75,7 @@ hidden long __syscall_ret(unsigned long), #define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f)) #define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f)) -#ifdef __EMSCRIPTEN__ -#define __syscall_cp(...) __syscall(__VA_ARGS__) -#else // !defined(__EMSCRIPTEN__) +#ifndef __EMSCRIPTEN__ #define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0) #define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0) #define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0) @@ -87,7 +85,9 @@ hidden long __syscall_ret(unsigned long), #define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) -#endif // !defined(__EMSCRIPTEN__) +#else // __EMSCRIPTEN__ +#define __syscall_cp(...) __syscall(__VA_ARGS__) +#endif // __EMSCRIPTEN__ #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) @@ -408,12 +408,7 @@ hidden long __syscall_ret(unsigned long), #define SIOCGSTAMPNS_OLD 0x8907 #endif -#ifdef __EMSCRIPTEN__ -#define __sys_open2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) -#define __sys_open3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) -#define __sys_open_cp2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) -#define __sys_open_cp3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) -#else // !defined(__EMSCRIPTEN__) +#ifndef __EMSCRIPTEN__ #ifdef SYS_open #define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) #define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) @@ -425,7 +420,13 @@ hidden long __syscall_ret(unsigned long), #define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) #define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) #endif -#endif // !defined(__EMSCRIPTEN__) +#else // __EMSCRIPTEN__ +#define __sys_open2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) +#define __sys_open3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) +#define __sys_open_cp2(x,pn,fl) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE)) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_openat(__scc(AT_FDCWD), __scc(pn), __scc((fl)|O_LARGEFILE), __scc(mo)) +#endif + #define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__) #define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__)) @@ -455,7 +456,7 @@ hidden long __emulate_wait4(int, int *, int, void *, int); #define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d)) #define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d)) -#ifdef __cplusplus // XXX Emscripten static array size is a C99 feature, not permitted in C++ +#ifdef __cplusplus hidden void __procfdname(char __buf[], unsigned); #else hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); diff --git a/system/lib/libc/musl/src/linux/sbrk.c b/system/lib/libc/musl/src/linux/sbrk.c index cf483a57fb329..8e3a9b6645d68 100644 --- a/system/lib/libc/musl/src/linux/sbrk.c +++ b/system/lib/libc/musl/src/linux/sbrk.c @@ -1,4 +1,4 @@ -#ifndef __EMSCRIPTEN__ /* Emscripten controls sbrk itself */ +#if !__EMSCRIPTEN__ /* Emscripten controls sbrk itself */ #define _BSD_SOURCE #include #include @@ -11,3 +11,4 @@ void *sbrk(intptr_t inc) return (void *)__syscall(SYS_brk, 0); } #endif + diff --git a/system/lib/libc/musl/src/math/sqrt.c b/system/lib/libc/musl/src/math/sqrt.c index 3b07abee8380a..6854c98381642 100644 --- a/system/lib/libc/musl/src/math/sqrt.c +++ b/system/lib/libc/musl/src/math/sqrt.c @@ -27,7 +27,7 @@ double sqrt(double x) { // XXX EMSCRIPTEN: use the wasm instruction via clang builtin // See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __EMSCRIPTEN__ +#ifdef __wasm__ return __builtin_sqrt(x); #else uint64_t ix, top, m; diff --git a/system/lib/libc/musl/src/math/sqrtf.c b/system/lib/libc/musl/src/math/sqrtf.c index d1f3b9595ccd0..fd74702691215 100644 --- a/system/lib/libc/musl/src/math/sqrtf.c +++ b/system/lib/libc/musl/src/math/sqrtf.c @@ -18,7 +18,7 @@ float sqrtf(float x) { // XXX EMSCRIPTEN: use the wasm instruction via clang builtin // See https://github.com/emscripten-core/emscripten/issues/9236 -#ifdef __EMSCRIPTEN__ +#ifdef __wasm__ return __builtin_sqrtf(x); #else uint32_t ix, m, m1, m0, even, ey; diff --git a/system/lib/libc/musl/src/network/freeaddrinfo.c b/system/lib/libc/musl/src/network/freeaddrinfo.c index 68fdc09cb9e10..c4016d9f7c246 100644 --- a/system/lib/libc/musl/src/network/freeaddrinfo.c +++ b/system/lib/libc/musl/src/network/freeaddrinfo.c @@ -6,7 +6,7 @@ void freeaddrinfo(struct addrinfo *p) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ // Emscripten's usage of this structure is very simple: we always allocate // ai_addr, and do not use the linked list aspect at all. There is also no // aliasing with aibuf. diff --git a/system/lib/libc/musl/src/sched/sched_yield.c b/system/lib/libc/musl/src/sched/sched_yield.c index 82a14a3914e95..7bd3846fc239e 100644 --- a/system/lib/libc/musl/src/sched/sched_yield.c +++ b/system/lib/libc/musl/src/sched/sched_yield.c @@ -1,7 +1,7 @@ #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ #include #include #include "threading_internal.h" @@ -9,7 +9,7 @@ int sched_yield() { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ // SharedArrayBuffer and wasm threads do not support explicit yielding. // For now we at least call `emscripten_yield` which processes the event queue // (along with other essential tasks). diff --git a/system/lib/libc/musl/src/stat/fchmod.c b/system/lib/libc/musl/src/stat/fchmod.c index ca2a6c783b2bd..58badd5c01bb8 100644 --- a/system/lib/libc/musl/src/stat/fchmod.c +++ b/system/lib/libc/musl/src/stat/fchmod.c @@ -9,7 +9,7 @@ int fchmod(int fd, mode_t mode) { int ret = __syscall(SYS_fchmod, fd, mode); -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ if (ret != -EBADF || !__wasi_fd_is_valid(fd)) return __syscall_ret(ret); #else diff --git a/system/lib/libc/musl/src/stat/fstatat.c b/system/lib/libc/musl/src/stat/fstatat.c index 6d499c44174a3..631451268c590 100644 --- a/system/lib/libc/musl/src/stat/fstatat.c +++ b/system/lib/libc/musl/src/stat/fstatat.c @@ -145,7 +145,7 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag) { int ret; -#ifdef __EMSCRIPTEN__ // XXX Emscripten statx syscall unsupported +#ifdef __EMSCRIPTEN__ // some logic here copied from fstatat_kstat above if (flag==AT_EMPTY_PATH && fd>=0 && !*path) ret = __syscall(SYS_fstat, fd, st); diff --git a/system/lib/libc/musl/src/stdio/__stdio_read.c b/system/lib/libc/musl/src/stdio/__stdio_read.c index c7adefe079f01..392a4858281f3 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_read.c +++ b/system/lib/libc/musl/src/stdio/__stdio_read.c @@ -8,7 +8,8 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) { .iov_base = f->buf, .iov_len = f->buf_size } }; ssize_t cnt; -#ifdef __EMSCRIPTEN__ + +#if __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_read(f->fd, (struct __wasi_iovec_t*)iov, 2, &num))) { num = -1; diff --git a/system/lib/libc/musl/src/stdio/__stdio_write.c b/system/lib/libc/musl/src/stdio/__stdio_write.c index b2de95cc7790e..7a125b89b928d 100644 --- a/system/lib/libc/musl/src/stdio/__stdio_write.c +++ b/system/lib/libc/musl/src/stdio/__stdio_write.c @@ -17,7 +17,7 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) iovcnt--; } for (;;) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_write(f->fd, (struct __wasi_ciovec_t*)iov, iovcnt, &num))) { num = -1; diff --git a/system/lib/libc/musl/src/stdio/stdout.c b/system/lib/libc/musl/src/stdio/stdout.c index 5054e5b6ccc14..62cf40220a5c4 100644 --- a/system/lib/libc/musl/src/stdio/stdout.c +++ b/system/lib/libc/musl/src/stdio/stdout.c @@ -1,6 +1,6 @@ #include "stdio_impl.h" -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ // Emscripten doesn't support terminal seeking. static off_t __emscripten_stdout_seek(FILE *f, off_t off, int whence) { @@ -23,7 +23,7 @@ hidden FILE __stdout_FILE = { .fd = 1, .flags = F_PERM | F_NORD, .lbf = '\n', -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ // avoid stout_write which adds special terminal window size handling, which emscripten doesn't support anyhow .write = __stdio_write, .seek = __emscripten_stdout_seek, diff --git a/system/lib/libc/musl/src/stdio/vfprintf.c b/system/lib/libc/musl/src/stdio/vfprintf.c index 1bfcb42c9bb06..96779841164ce 100644 --- a/system/lib/libc/musl/src/stdio/vfprintf.c +++ b/system/lib/libc/musl/src/stdio/vfprintf.c @@ -147,7 +147,7 @@ typedef void (*pop_arg_long_double_t)(union arg *arg, va_list *ap); static void pop_arg_long_double(union arg *arg, va_list *ap) { - arg->f = va_arg(*ap, long double); + arg->f = va_arg(*ap, long double); } static void pop_arg(union arg *arg, int type, va_list *ap, pop_arg_long_double_t pop_arg_long_double) diff --git a/system/lib/libc/musl/src/string/memcmp.c b/system/lib/libc/musl/src/string/memcmp.c index ba9ab6d41d3c9..c93cf8cc97330 100644 --- a/system/lib/libc/musl/src/string/memcmp.c +++ b/system/lib/libc/musl/src/string/memcmp.c @@ -1,4 +1,4 @@ -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ #include #endif #include diff --git a/system/lib/libc/musl/src/thread/__timedwait.c b/system/lib/libc/musl/src/thread/__timedwait.c index 51afba0044942..9e3ccc9849257 100644 --- a/system/lib/libc/musl/src/thread/__timedwait.c +++ b/system/lib/libc/musl/src/thread/__timedwait.c @@ -32,10 +32,10 @@ static int __futex4_cp(volatile void *addr, int op, int val, const struct timesp if (r != -ENOSYS) return r; return __syscall_cp(SYS_futex, addr, op & ~FUTEX_PRIVATE, val, to); } +#endif static volatile int dummy = 0; weak_alias(dummy, __eintr_valid_flag); -#endif int __timedwait_cp(volatile int *addr, int val, clockid_t clk, const struct timespec *at, int priv) @@ -64,13 +64,11 @@ int __timedwait_cp(volatile int *addr, int val, r = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top); #endif if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0; -#ifndef __EMSCRIPTEN__ // XXX Emscripten revert musl commit a63c0104e496f7ba78b64be3cd299b41e8cd427f /* Mitigate bug in old kernels wrongly reporting EINTR for non- * interrupting (SA_RESTART) signal handlers. This is only practical * when NO interrupting signal handlers have been installed, and * works by sigaction tracking whether that's the case. */ if (r == EINTR && !__eintr_valid_flag) r = 0; -#endif return r; } diff --git a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c index 95eefb45ea0a8..232c9b321a8e2 100644 --- a/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c +++ b/system/lib/libc/musl/src/thread/pthread_mutex_timedlock.c @@ -77,7 +77,7 @@ int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec #ifndef __EMSCRIPTEN__ if (type&8) return pthread_mutex_timedlock_pi(m, at); #endif - + int spins = 100; while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); diff --git a/system/lib/libc/musl/src/time/clock_gettime.c b/system/lib/libc/musl/src/time/clock_gettime.c index 36d901e85dff1..18926de8ce8f3 100644 --- a/system/lib/libc/musl/src/time/clock_gettime.c +++ b/system/lib/libc/musl/src/time/clock_gettime.c @@ -56,7 +56,7 @@ static void *volatile vdso_func = (void *)cgt_init; #endif -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ _Static_assert(CLOCK_REALTIME == __WASI_CLOCKID_REALTIME, "monotonic clock must match"); _Static_assert(CLOCK_MONOTONIC == __WASI_CLOCKID_MONOTONIC, "monotonic clock must match"); diff --git a/system/lib/libc/musl/src/time/clock_nanosleep.c b/system/lib/libc/musl/src/time/clock_nanosleep.c index 3684e43aa14c6..7ad2aba1a0b7a 100644 --- a/system/lib/libc/musl/src/time/clock_nanosleep.c +++ b/system/lib/libc/musl/src/time/clock_nanosleep.c @@ -1,7 +1,7 @@ #include #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ #include #include #endif @@ -12,7 +12,7 @@ int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem) { if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL; -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999L || req->tv_sec < 0) { return EINVAL; } diff --git a/system/lib/libc/musl/src/time/clock_settime.c b/system/lib/libc/musl/src/time/clock_settime.c index 686488414371a..ed0182fff664c 100644 --- a/system/lib/libc/musl/src/time/clock_settime.c +++ b/system/lib/libc/musl/src/time/clock_settime.c @@ -1,6 +1,9 @@ #include #include #include "syscall.h" +#ifdef __EMSCRIPTEN__ +#include +#endif #define IS32BIT(x) !((x)+0x80000000ULL>>32) @@ -10,7 +13,8 @@ int clock_settime(clockid_t clk, const struct timespec *ts) // JS and wasm VMs do not allow setting the time. errno = EPERM; return -1; -#elif defined(SYS_clock_settime64) // XXX EMSCRIPTEN replace #ifdef SYS_clock_settime64 +#else +#ifdef SYS_clock_settime64 time_t s = ts->tv_sec; long ns = ts->tv_nsec; int r = -ENOSYS; @@ -25,4 +29,5 @@ int clock_settime(clockid_t clk, const struct timespec *ts) #else return syscall(SYS_clock_settime, clk, ts); #endif +#endif } diff --git a/system/lib/libc/musl/src/unistd/fchdir.c b/system/lib/libc/musl/src/unistd/fchdir.c index a22f5f4fed65d..bcbd0fc9cc9cd 100644 --- a/system/lib/libc/musl/src/unistd/fchdir.c +++ b/system/lib/libc/musl/src/unistd/fchdir.c @@ -9,7 +9,7 @@ int fchdir(int fd) { int ret = __syscall(SYS_fchdir, fd); -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ if (ret != -EBADF || !__wasi_fd_is_valid(fd)) return __syscall_ret(ret); #else diff --git a/system/lib/libc/musl/src/unistd/fchown.c b/system/lib/libc/musl/src/unistd/fchown.c index 02facc410b5d1..a328189505444 100644 --- a/system/lib/libc/musl/src/unistd/fchown.c +++ b/system/lib/libc/musl/src/unistd/fchown.c @@ -9,7 +9,7 @@ int fchown(int fd, uid_t uid, gid_t gid) { int ret = __syscall(SYS_fchown, fd, uid, gid); -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ // We can't continue onwards to try the /proc/fd/NNN approach that musl does, // as we don't support that much of POSIX. return __syscall_ret(ret); @@ -24,5 +24,5 @@ int fchown(int fd, uid_t uid, gid_t gid) #else return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0); #endif -#endif // __EMSCRIPTEN__ +#endif // EMSCRIPTEN } diff --git a/system/lib/libc/musl/src/unistd/fsync.c b/system/lib/libc/musl/src/unistd/fsync.c index 8c6c1d13dcc5d..2b26be534e96c 100644 --- a/system/lib/libc/musl/src/unistd/fsync.c +++ b/system/lib/libc/musl/src/unistd/fsync.c @@ -3,7 +3,7 @@ int fsync(int fd) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ return __wasi_syscall_ret(__wasi_fd_sync(fd)); #else return syscall_cp(SYS_fsync, fd); diff --git a/system/lib/libc/musl/src/unistd/pread.c b/system/lib/libc/musl/src/unistd/pread.c index 7b790d47d1abc..a2361a0473b51 100644 --- a/system/lib/libc/musl/src/unistd/pread.c +++ b/system/lib/libc/musl/src/unistd/pread.c @@ -3,7 +3,7 @@ ssize_t pread(int fd, void *buf, size_t size, off_t ofs) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ __wasi_iovec_t iov = { .buf = buf, .buf_len = size diff --git a/system/lib/libc/musl/src/unistd/preadv.c b/system/lib/libc/musl/src/unistd/preadv.c index 5c86d09cf2c7d..fa6b78c101b3f 100644 --- a/system/lib/libc/musl/src/unistd/preadv.c +++ b/system/lib/libc/musl/src/unistd/preadv.c @@ -5,7 +5,7 @@ ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_pread(fd, (struct __wasi_iovec_t*)iov, count, ofs, &num))) { return -1; diff --git a/system/lib/libc/musl/src/unistd/pwrite.c b/system/lib/libc/musl/src/unistd/pwrite.c index 895afdc5533e3..4b2035ade9ea4 100644 --- a/system/lib/libc/musl/src/unistd/pwrite.c +++ b/system/lib/libc/musl/src/unistd/pwrite.c @@ -6,7 +6,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ __wasi_ciovec_t iov = { .buf = buf, .buf_len = size diff --git a/system/lib/libc/musl/src/unistd/pwritev.c b/system/lib/libc/musl/src/unistd/pwritev.c index f011649af40f9..d4f03899d73d0 100644 --- a/system/lib/libc/musl/src/unistd/pwritev.c +++ b/system/lib/libc/musl/src/unistd/pwritev.c @@ -6,7 +6,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_pwrite(fd, (struct __wasi_ciovec_t*)iov, count, ofs, &num))) { return -1; diff --git a/system/lib/libc/musl/src/unistd/read.c b/system/lib/libc/musl/src/unistd/read.c index f84e9436c7c8b..f079439c9d302 100644 --- a/system/lib/libc/musl/src/unistd/read.c +++ b/system/lib/libc/musl/src/unistd/read.c @@ -3,7 +3,7 @@ ssize_t read(int fd, void *buf, size_t count) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ __wasi_iovec_t iov = { .buf = buf, .buf_len = count diff --git a/system/lib/libc/musl/src/unistd/readv.c b/system/lib/libc/musl/src/unistd/readv.c index 3a40c1e9626f6..bb0760da6e147 100644 --- a/system/lib/libc/musl/src/unistd/readv.c +++ b/system/lib/libc/musl/src/unistd/readv.c @@ -3,7 +3,7 @@ ssize_t readv(int fd, const struct iovec *iov, int count) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_read(fd, (struct __wasi_iovec_t*)iov, count, &num))) { num = -1; diff --git a/system/lib/libc/musl/src/unistd/write.c b/system/lib/libc/musl/src/unistd/write.c index 135229be89121..53742cd4fd972 100644 --- a/system/lib/libc/musl/src/unistd/write.c +++ b/system/lib/libc/musl/src/unistd/write.c @@ -3,7 +3,7 @@ ssize_t write(int fd, const void *buf, size_t count) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ __wasi_ciovec_t iov = { .buf = buf, .buf_len = count diff --git a/system/lib/libc/musl/src/unistd/writev.c b/system/lib/libc/musl/src/unistd/writev.c index 4e81f107f61fb..443d14f35d1be 100644 --- a/system/lib/libc/musl/src/unistd/writev.c +++ b/system/lib/libc/musl/src/unistd/writev.c @@ -1,12 +1,12 @@ #include #include "syscall.h" -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ #include #endif ssize_t writev(int fd, const struct iovec *iov, int count) { -#ifdef __EMSCRIPTEN__ +#if __EMSCRIPTEN__ size_t num; if (__wasi_syscall_ret(__wasi_fd_write(fd, (struct __wasi_ciovec_t*)iov, count, &num))) { return -1; From 9ac8462e58843d3a5ae1424128e254d8ba267dd4 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 6 May 2026 18:26:23 +0200 Subject: [PATCH 17/17] Remove generic `` header In-line with: https://git.musl-libc.org/cgit/musl/commit?id=ffaaa6d230512f3a7f3d040b943517728f3dc3cf --- system/lib/libc/musl/arch/generic/bits/stdarg.h | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 system/lib/libc/musl/arch/generic/bits/stdarg.h diff --git a/system/lib/libc/musl/arch/generic/bits/stdarg.h b/system/lib/libc/musl/arch/generic/bits/stdarg.h deleted file mode 100644 index fde378146d5df..0000000000000 --- a/system/lib/libc/musl/arch/generic/bits/stdarg.h +++ /dev/null @@ -1,4 +0,0 @@ -#define va_start(v,l) __builtin_va_start(v,l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v,l) __builtin_va_arg(v,l) -#define va_copy(d,s) __builtin_va_copy(d,s)