From 332ef25b89f38230b966a33d70bc54d621f8e14b Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 16 Jul 2025 23:30:53 +0000 Subject: [PATCH] Add downstream changes from emscripten --- .../lib/sanitizer_common/sanitizer_linux.cpp | 134 ++++-------------- .../sanitizer_platform_interceptors.h | 2 +- .../sanitizer_platform_limits_posix.h | 14 +- .../sanitizer_syscall_generic.inc | 6 +- libcxx/include/__verbose_abort | 5 +- libcxx/src/verbose_abort.cpp | 7 + 6 files changed, 53 insertions(+), 115 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 0a77861b1af11..538f0570e131b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -115,15 +115,8 @@ extern struct ps_strings *__ps_strings; # endif # if SANITIZER_EMSCRIPTEN -# define weak __attribute__(__weak__) -# define hidden __attribute__((__visibility__("hidden"))) -# include -# undef weak -# undef hidden -# include -# include -# include -# include +# include // For INFINITY +# include // For emscripten_futex_wait # endif extern char **environ; @@ -254,8 +247,8 @@ ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); } # endif // --------------- sanitizer_libc.h -# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD -# if !SANITIZER_S390 && !SANITIZER_EMSCRIPTEN +# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN +# if !SANITIZER_S390 uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, u64 offset) { # if SANITIZER_FREEBSD @@ -270,25 +263,23 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, (OFF_T)(offset / 4096)); # endif } -# endif // !SANITIZER_S390 && !SANITIZER_EMSCRIPTEN +# endif // !SANITIZER_S390 -# if !SANITIZER_EMSCRIPTEN uptr internal_munmap(void *addr, uptr length) { return internal_syscall(SYSCALL(munmap), (uptr)addr, length); } -# if SANITIZER_LINUX +# if SANITIZER_LINUX uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags, void *new_address) { return internal_syscall(SYSCALL(mremap), (uptr)old_address, old_size, new_size, flags, (uptr)new_address); } -# endif +# endif int internal_mprotect(void *addr, uptr length, int prot) { return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot); } -# endif int internal_madvise(uptr addr, uptr length, int advice) { return internal_syscall(SYSCALL(madvise), addr, length, advice); @@ -299,17 +290,10 @@ uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) { return internal_syscall(SYSCALL(close_range), lowfd, highfd, flags); } # endif - -uptr internal_close(fd_t fd) { -# if SANITIZER_EMSCRIPTEN - return __wasi_fd_close(fd); -# else - return internal_syscall(SYSCALL(close), fd); -# endif -} +uptr internal_close(fd_t fd) { return internal_syscall(SYSCALL(close), fd); } uptr internal_open(const char *filename, int flags) { -# if SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +# if SANITIZER_LINUX return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags); # else return internal_syscall(SYSCALL(open), (uptr)filename, flags); @@ -317,7 +301,7 @@ uptr internal_open(const char *filename, int flags) { } uptr internal_open(const char *filename, int flags, u32 mode) { -# if SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +# if SANITIZER_LINUX return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags, mode); # else @@ -326,35 +310,17 @@ uptr internal_open(const char *filename, int flags, u32 mode) { } uptr internal_read(fd_t fd, void *buf, uptr count) { -# if SANITIZER_EMSCRIPTEN - __wasi_iovec_t iov = {(uint8_t *)buf, count}; - size_t num; - if (__wasi_syscall_ret(__wasi_fd_read(fd, &iov, 1, &num))) { - return -1; - } - return num; -# else sptr res; HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf, count)); return res; -# endif } uptr internal_write(fd_t fd, const void *buf, uptr count) { -# if SANITIZER_EMSCRIPTEN - __wasi_ciovec_t iov = {(const uint8_t *)buf, count}; - size_t num; - if (__wasi_syscall_ret(__wasi_fd_write(fd, &iov, 1, &num))) { - return -1; - } - return num; -# else sptr res; HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf, count)); return res; -# endif } uptr internal_ftruncate(fd_t fd, uptr size) { @@ -577,7 +543,7 @@ uptr internal_filesize(fd_t fd) { uptr internal_dup(int oldfd) { return internal_syscall(SYSCALL(dup), oldfd); } uptr internal_dup2(int oldfd, int newfd) { -# if SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +# if SANITIZER_LINUX return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0); # else return internal_syscall(SYSCALL(dup2), oldfd, newfd); @@ -585,7 +551,7 @@ uptr internal_dup2(int oldfd, int newfd) { } uptr internal_readlink(const char *path, char *buf, uptr bufsize) { -# if SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +# if SANITIZER_LINUX return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf, bufsize); # else @@ -594,7 +560,7 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) { } uptr internal_unlink(const char *path) { -# if SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +# if SANITIZER_LINUX return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0); # else return internal_syscall(SYSCALL(unlink), (uptr)path); @@ -605,7 +571,7 @@ uptr internal_rename(const char *oldpath, const char *newpath) { # if (defined(__riscv) || defined(__loongarch__)) && defined(__linux__) return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath, 0); -# elif SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +# elif SANITIZER_LINUX return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath); # else @@ -613,46 +579,32 @@ uptr internal_rename(const char *oldpath, const char *newpath) { # endif } -uptr internal_sched_yield() { -# if SANITIZER_EMSCRIPTEN - return 0; -# else - return internal_syscall(SYSCALL(sched_yield)); -# endif -} +uptr internal_sched_yield() { return internal_syscall(SYSCALL(sched_yield)); } void internal_usleep(u64 useconds) { -# if SANITIZER_EMSCRIPTEN - usleep(useconds); -# else struct timespec ts; ts.tv_sec = useconds / 1000000; ts.tv_nsec = (useconds % 1000000) * 1000; internal_syscall(SYSCALL(nanosleep), &ts, &ts); -# endif } -# if !SANITIZER_EMSCRIPTEN uptr internal_execve(const char *filename, char *const argv[], char *const envp[]) { return internal_syscall(SYSCALL(execve), (uptr)filename, (uptr)argv, (uptr)envp); } -# endif // !SANITIZER_EMSCRIPTEN -# endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD +# endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN -# if !SANITIZER_NETBSD +# if !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN void internal__exit(int exitcode) { -# if SANITIZER_EMSCRIPTEN - __wasi_proc_exit(exitcode); -# elif SANITIZER_FREEBSD || SANITIZER_SOLARIS +# if SANITIZER_FREEBSD || SANITIZER_SOLARIS internal_syscall(SYSCALL(exit), exitcode); # else internal_syscall(SYSCALL(exit_group), exitcode); # endif Die(); // Unreachable. } -# endif // !SANITIZER_NETBSD +# endif // !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN // ----------------- sanitizer_common.h bool FileExists(const char *filename) { @@ -672,7 +624,7 @@ bool DirExists(const char *path) { return S_ISDIR(st.st_mode); } -# if !SANITIZER_NETBSD +# if !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN tid_t GetTid() { # if SANITIZER_FREEBSD long Tid; @@ -680,8 +632,6 @@ tid_t GetTid() { return Tid; # elif SANITIZER_SOLARIS return thr_self(); -# elif SANITIZER_EMSCRIPTEN - return (tid_t)pthread_self(); # else return internal_syscall(SYSCALL(gettid)); # endif @@ -722,16 +672,6 @@ u64 NanoTime() { } # endif -# if SANITIZER_EMSCRIPTEN -extern "C" { -int __clock_gettime(__sanitizer_clockid_t clk_id, void *tp); -} - -uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { - return __clock_gettime(clk_id, tp); -} -# endif - // Like getenv, but reads env directly from /proc (on Linux) or parses the // 'environ' array (on some others) and does not use libc. This function // should be called first inside __asan_init. @@ -916,14 +856,12 @@ struct linux_dirent { }; # endif -# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD -# if !SANITIZER_EMSCRIPTEN +# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN // Syscall wrappers. uptr internal_ptrace(int request, int pid, void *addr, void *data) { return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr, (uptr)data); } -# endif uptr internal_waitpid(int pid, int *status, int options) { return internal_syscall(SYSCALL(wait4), pid, (uptr)status, options, @@ -953,14 +891,7 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { } uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { -# if SANITIZER_EMSCRIPTEN - __wasi_filesize_t result; - return __wasi_syscall_ret(__wasi_fd_seek(fd, offset, whence, &result)) - ? -1 - : result; -# else return internal_syscall(SYSCALL(lseek), fd, offset, whence); -# endif } # if SANITIZER_LINUX @@ -976,32 +907,25 @@ uptr internal_arch_prctl(int option, uptr arg2) { # endif # endif -# if !SANITIZER_EMSCRIPTEN uptr internal_sigaltstack(const void *ss, void *oss) { return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss); } -# endif extern "C" pid_t __fork(void); int internal_fork() { -# if SANITIZER_EMSCRIPTEN - Report("fork not supported on emscripten\n"); - return -1; -# else -# if SANITIZER_LINUX -# if SANITIZER_S390 +# if SANITIZER_LINUX +# if SANITIZER_S390 return internal_syscall(SYSCALL(clone), 0, SIGCHLD); -# elif SANITIZER_SPARC +# elif SANITIZER_SPARC // The clone syscall interface on SPARC differs massively from the rest, // so fall back to __fork. return __fork(); -# else - return internal_syscall(SYSCALL(clone), SIGCHLD, 0); -# endif # else - return internal_syscall(SYSCALL(fork)); + return internal_syscall(SYSCALL(clone), SIGCHLD, 0); # endif +# else + return internal_syscall(SYSCALL(fork)); # endif } @@ -1093,8 +1017,6 @@ uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) { # if SANITIZER_FREEBSD return internal_syscall(SYSCALL(sigprocmask), how, set, oldset); -# elif SANITIZER_EMSCRIPTEN - return 0; # else __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set; __sanitizer_kernel_sigset_t *k_oldset = (__sanitizer_kernel_sigset_t *)oldset; @@ -1146,7 +1068,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { return sigismember(rset, signum); } # endif -# endif // !SANITIZER_SOLARIS +# endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN # if !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN // ThreadLister implementation. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 15a72d2d714d1..3cc84b995c62f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -308,7 +308,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_SENDMMSG SI_LINUX #define SANITIZER_INTERCEPT_SYSMSG SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_GETPEERNAME SI_POSIX -#define SANITIZER_INTERCEPT_IOCTL SI_POSIX && !SI_EMSCRIPTEN +#define SANITIZER_INTERCEPT_IOCTL SI_POSIX_NOT_EMSCRIPTEN #define SANITIZER_INTERCEPT_INET_ATON SI_POSIX #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index cb60606f9cbd3..aa05c4f577791 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -38,6 +38,11 @@ #define SANITIZER_HAS_STATFS64 1 #endif +#if SANITIZER_EMSCRIPTEN +#include // For sigset_t +#include // For clock_t and clockid_t +#endif + #if defined(__sparc__) // FIXME: This can't be included from tsan which does not support sparc yet. #include "sanitizer_glibc_version.h" @@ -534,16 +539,19 @@ extern unsigned struct_sock_fprog_sz; #endif #if SANITIZER_EMSCRIPTEN -typedef int __sanitizer_clock_t; +typedef clock_t __sanitizer_clock_t; #elif defined(__x86_64__) && !defined(_LP64) typedef long long __sanitizer_clock_t; #else typedef long __sanitizer_clock_t; #endif -#if SANITIZER_LINUX || SANITIZER_EMSCRIPTEN +#if SANITIZER_LINUX typedef int __sanitizer_clockid_t; typedef unsigned long long __sanitizer_eventfd_t; +#elif SANITIZER_EMSCRIPTEN +typedef clockid_t __sanitizer_clockid_t; +// eventfd is Unix-specific. #endif #if SANITIZER_LINUX @@ -596,7 +604,7 @@ struct __sanitizer_sigset_t { uptr val[128 / sizeof(uptr)]; }; #elif SANITIZER_EMSCRIPTEN -typedef unsigned long __sanitizer_sigset_t; +typedef sigset_t __sanitizer_sigset_t; #endif struct __sanitizer_siginfo_pad { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc b/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc index ae2cea517c1f9..2780f885d5ab8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -// NetBSD uses libc calls directly -#if !SANITIZER_NETBSD +// NetBSD and Emscripten uses libc calls directly +#if !SANITIZER_NETBSD && !SANITIZER_EMSCRIPTEN -#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_SOLARIS # define SYSCALL(name) SYS_ ## name #else # define SYSCALL(name) __NR_ ## name diff --git a/libcxx/include/__verbose_abort b/libcxx/include/__verbose_abort index d3db2afc8c6e2..c66a45ca378db 100644 --- a/libcxx/include/__verbose_abort +++ b/libcxx/include/__verbose_abort @@ -43,8 +43,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD // make sure that the program terminates but without taking any complex dependencies in this header. #if !defined(_LIBCPP_VERBOSE_ABORT) -// XXX EMSCRIPTEN __libcpp_verbose_abort creases code size too much -# if !_LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT || defined (__EMSCRIPTEN__) +// XXX EMSCRIPTEN avoid __libcpp_verbose_abort in release builds due to code +// size +# if !_LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT || (defined(__EMSCRIPTEN__) && defined(NDEBUG)) // The decltype is there to suppress -Wunused warnings in this configuration. void __use(const char*, ...); # define _LIBCPP_VERBOSE_ABORT(...) (decltype(::std::__use(__VA_ARGS__))(), __builtin_abort()) diff --git a/libcxx/src/verbose_abort.cpp b/libcxx/src/verbose_abort.cpp index fd6bc4943d6ba..707e62ddc81a4 100644 --- a/libcxx/src/verbose_abort.cpp +++ b/libcxx/src/verbose_abort.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef __BIONIC__ # include @@ -30,6 +31,12 @@ _LIBCPP_WEAK void __libcpp_verbose_abort(char const* format, ...) _LIBCPP_VERBOS va_list list; va_start(list, format); std::vfprintf(stderr, format, list); + // TODO(sbc): Add newline here unconditionally. libc++ seems inconsistent about strings + // passed to __libcpp_verbose_abort. The _LIBCPP_VERBOSE_ABORT macro seems to never use + // newlines, but _LIBCPP_ASSERTION_HANDLER does include a newline. + if (format[strlen(format) - 1] != '\n') { + std::fputc('\n', stderr); + } va_end(list); }