Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package wasi-libc for openSUSE:Factory checked in at 2024-02-25 14:04:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wasi-libc (Old) and /work/SRC/openSUSE:Factory/.wasi-libc.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wasi-libc" Sun Feb 25 14:04:45 2024 rev:5 rq:1149694 version:21 Changes: -------- --- /work/SRC/openSUSE:Factory/wasi-libc/wasi-libc.changes 2024-02-22 20:55:23.544332807 +0100 +++ /work/SRC/openSUSE:Factory/.wasi-libc.new.1770/wasi-libc.changes 2024-02-25 14:04:47.282010104 +0100 @@ -1,0 +2,8 @@ +Thu Feb 22 21:05:54 UTC 2024 - Aaron Puchert <aaronpuch...@alice-dsl.net> + +- Update to version (wasi-sdk-)21. + * Compatibility with Clang 18. + * Add shared library support. +- Drop obsolete ignore-fpclass-macros.patch. + +------------------------------------------------------------------- Old: ---- ignore-fpclass-macros.patch wasi-libc-20.tar.gz New: ---- wasi-libc-21.tar.gz BETA DEBUG BEGIN: Old: * Add shared library support. - Drop obsolete ignore-fpclass-macros.patch. BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wasi-libc.spec ++++++ --- /var/tmp/diff_new_pack.6ifjT7/_old 2024-02-25 14:04:49.210079841 +0100 +++ /var/tmp/diff_new_pack.6ifjT7/_new 2024-02-25 14:04:49.210079841 +0100 @@ -1,7 +1,7 @@ # # spec file for package wasi-libc # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: wasi-libc -Version: 20 +Version: 21 Release: 0 Summary: WASI libc implementation for WebAssembly # FIXME: Select a correct license from https://github.com/openSUSE/spec-cleaner#spdx-licenses @@ -26,7 +26,6 @@ Source: https://github.com/WebAssembly/wasi-libc/archive/refs/tags/wasi-sdk-%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: wasi-libc-rpmlintrc Patch1: workaround-broken-makefile.patch -Patch2: ignore-fpclass-macros.patch BuildRequires: clang > 10 BuildRequires: llvm > 10 BuildArch: noarch ++++++ wasi-libc-20.tar.gz -> wasi-libc-21.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/.github/workflows/main.yml new/wasi-libc-wasi-sdk-21/.github/workflows/main.yml --- old/wasi-libc-wasi-sdk-20/.github/workflows/main.yml 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/.github/workflows/main.yml 2023-12-15 19:07:28.000000000 +0100 @@ -8,8 +8,26 @@ strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - # oldest and newest supported LLVM version - clang_version: [10.0.0, 14.0.0] + clang_version: [10.0.0] + # use different LLVM versions among oses because of the lack of + # official assets on github. + include: + - os: ubuntu-latest + clang_version: 10.0.0 + llvm_asset_suffix: x86_64-linux-gnu-ubuntu-18.04 + - os: macos-latest + clang_version: 10.0.0 + llvm_asset_suffix: x86_64-apple-darwin + - os: windows-latest + clang_version: 10.0.0 + - os: ubuntu-latest + clang_version: 16.0.0 + llvm_asset_suffix: x86_64-linux-gnu-ubuntu-18.04 + - os: macos-latest + clang_version: 15.0.7 + llvm_asset_suffix: x86_64-apple-darwin21.0 + - os: windows-latest + clang_version: 16.0.0 steps: - uses: actions/checkout@v1 with: @@ -44,8 +62,8 @@ - name: Install LLVM tools (MacOS) shell: bash run: | - curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-x86_64-apple-darwin.tar.xz | tar xJf - - export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-x86_64-apple-darwin/bin + curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}.tar.xz | tar xJf - + export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}/bin echo "$CLANG_DIR" >> $GITHUB_PATH echo "CC=$CLANG_DIR/clang" >> $GITHUB_ENV echo "AR=$CLANG_DIR/llvm-ar" >> $GITHUB_ENV @@ -55,8 +73,8 @@ - name: Install LLVM tools (Linux) shell: bash run: | - curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-x86_64-linux-gnu-ubuntu-18.04.tar.xz | tar xJf - - export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-x86_64-linux-gnu-ubuntu-18.04/bin + curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-${{ matrix.clang_version }}/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}.tar.xz | tar xJf - + export CLANG_DIR=`pwd`/clang+llvm-${{ matrix.clang_version }}-${{ matrix.llvm_asset_suffix }}/bin echo "$CLANG_DIR" >> $GITHUB_PATH echo "CLANG_DIR=$CLANG_DIR" >> $GITHUB_ENV echo "CC=$CLANG_DIR/clang" >> $GITHUB_ENV @@ -76,12 +94,14 @@ run: | cd test make download - export WASI_DIR=$(realpath $CLANG_DIR/../lib/clang/${{ matrix.clang_version }}/lib/wasi/) + export WASI_DIR=$(realpath $($CLANG_DIR/clang -print-resource-dir)/lib/wasi/) mkdir -p $WASI_DIR cp download/lib/wasi/libclang_rt.builtins-wasm32.a $WASI_DIR make test # The older version of Clang does not provide the expected symbol for the # test entrypoints: `undefined symbol: __main_argc_argv`. + # The older (<15.0.7) version of wasm-ld does not provide `__heap_end`, + # which is required by our malloc implementation. if: matrix.os == 'ubuntu-latest' && matrix.clang_version != '10.0.0' - uses: actions/upload-artifact@v1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/Makefile new/wasi-libc-wasi-sdk-21/Makefile --- old/wasi-libc-wasi-sdk-20/Makefile 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/Makefile 2023-12-15 19:07:28.000000000 +0100 @@ -41,6 +41,8 @@ TARGET_TRIPLE = wasm32-wasi-threads endif +BUILTINS_LIB ?= $(shell ${CC} --print-libgcc-file-name) + # These variables describe the locations of various files and directories in # the source tree. DLMALLOC_DIR = dlmalloc @@ -78,6 +80,7 @@ LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES = \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/signal/psignal.c \ $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/strsignal.c +LIBDL_SOURCES = $(LIBC_TOP_HALF_MUSL_SRC_DIR)/misc/dl.c LIBC_BOTTOM_HALF_CRT_SOURCES = $(wildcard $(LIBC_BOTTOM_HALF_DIR)/crt/*.c) LIBC_TOP_HALF_DIR = libc-top-half LIBC_TOP_HALF_MUSL_DIR = $(LIBC_TOP_HALF_DIR)/musl @@ -325,6 +328,7 @@ # Specify the tls-model until LLVM 15 is released (which should contain # https://reviews.llvm.org/D130053). CFLAGS += -mthread-model posix -pthread -ftls-model=local-exec +ASMFLAGS += -matomics # Include cloudlib's directory to access the structure definition of clockid_t CFLAGS += -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC) @@ -376,6 +380,7 @@ LIBWASI_EMULATED_GETPID_OBJS = $(call objs,$(LIBWASI_EMULATED_GETPID_SOURCES)) LIBWASI_EMULATED_SIGNAL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_SOURCES)) LIBWASI_EMULATED_SIGNAL_MUSL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES)) +LIBDL_OBJS = $(call objs,$(LIBDL_SOURCES)) LIBC_BOTTOM_HALF_CRT_OBJS = $(call objs,$(LIBC_BOTTOM_HALF_CRT_SOURCES)) # These variables describe the locations of various files and @@ -442,7 +447,6 @@ "netdb.h" \ "resolv.h" \ "pty.h" \ - "dlfcn.h" \ "setjmp.h" \ "ulimit.h" \ "sys/xattr.h" \ @@ -471,6 +475,57 @@ default: finish +LIBC_SO_OBJS = $(patsubst %.o,%.pic.o,$(filter-out $(MUSL_PRINTSCAN_OBJS),$(LIBC_OBJS))) +MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS = $(patsubst %.o,%.pic.o,$(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS)) +LIBWASI_EMULATED_MMAN_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_MMAN_OBJS)) +LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS)) +LIBWASI_EMULATED_GETPID_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_GETPID_OBJS)) +LIBWASI_EMULATED_SIGNAL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_SIGNAL_OBJS)) +LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS)) +LIBDL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBDL_OBJS)) +BULK_MEMORY_SO_OBJS = $(patsubst %.o,%.pic.o,$(BULK_MEMORY_OBJS)) +DLMALLOC_SO_OBJS = $(patsubst %.o,%.pic.o,$(DLMALLOC_OBJS)) +LIBC_BOTTOM_HALF_ALL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBC_BOTTOM_HALF_ALL_OBJS)) +LIBC_TOP_HALF_ALL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBC_TOP_HALF_ALL_OBJS)) + +PIC_OBJS = \ + $(LIBC_SO_OBJS) \ + $(MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS) \ + $(LIBWASI_EMULATED_MMAN_SO_OBJS) \ + $(LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS) \ + $(LIBWASI_EMULATED_GETPID_SO_OBJS) \ + $(LIBWASI_EMULATED_SIGNAL_SO_OBJS) \ + $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS) \ + $(LIBDL_SO_OBJS) \ + $(BULK_MEMORY_SO_OBJS) \ + $(DLMALLOC_SO_OBJS) \ + $(LIBC_BOTTOM_HALF_ALL_SO_OBJS) \ + $(LIBC_TOP_HALF_ALL_SO_OBJS) \ + $(LIBC_BOTTOM_HALF_CRT_OBJS) + +# TODO: Specify SDK version, e.g. libc.so.wasi-sdk-21, as SO_NAME once `wasm-ld` +# supports it. +# +# Note that we collect the object files for each shared library into a .a and +# link that using `--whole-archive` rather than pass the object files directly +# to CC. This is a workaround for a Windows command line size limitation. See +# the `%.a` rule below for details. +$(SYSROOT_LIB)/%.so: $(OBJDIR)/%.so.a $(BUILTINS_LIB) + $(CC) -nodefaultlibs -shared --sysroot=$(SYSROOT) \ + -o $@ -Wl,--whole-archive $< -Wl,--no-whole-archive $(BUILTINS_LIB) + +$(OBJDIR)/libc.so.a: $(LIBC_SO_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS) + +$(OBJDIR)/libwasi-emulated-mman.so.a: $(LIBWASI_EMULATED_MMAN_SO_OBJS) + +$(OBJDIR)/libwasi-emulated-process-clocks.so.a: $(LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS) + +$(OBJDIR)/libwasi-emulated-getpid.so.a: $(LIBWASI_EMULATED_GETPID_SO_OBJS) + +$(OBJDIR)/libwasi-emulated-signal.so.a: $(LIBWASI_EMULATED_SIGNAL_SO_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS) + +$(OBJDIR)/libdl.so.a: $(LIBDL_SO_OBJS) + $(SYSROOT_LIB)/libc.a: $(LIBC_OBJS) $(SYSROOT_LIB)/libc-printscan-long-double.a: $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) @@ -485,6 +540,8 @@ $(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS) +$(SYSROOT_LIB)/libdl.a: $(LIBDL_OBJS) + %.a: @mkdir -p "$(@D)" # On Windows, the commandline for the ar invocation got too long, so it needs to be split up. @@ -496,6 +553,8 @@ # silently dropping the tail. $(AR) crs $@ $(wordlist 800, 100000, $(sort $^)) +$(PIC_OBJS): CFLAGS += -fPIC -fvisibility=default + $(MUSL_PRINTSCAN_OBJS): CFLAGS += \ -D__wasilibc_printscan_no_long_double \ -D__wasilibc_printscan_full_support_option="\"add -lc-printscan-long-double to the link command\"" @@ -506,15 +565,23 @@ # TODO: apply -mbulk-memory globally, once # https://github.com/llvm/llvm-project/issues/52618 is resolved -$(BULK_MEMORY_OBJS): CFLAGS += \ +$(BULK_MEMORY_OBJS) $(BULK_MEMORY_SO_OBJS): CFLAGS += \ -mbulk-memory -$(BULK_MEMORY_OBJS): CFLAGS += \ +$(BULK_MEMORY_OBJS) $(BULK_MEMORY_SO_OBJS): CFLAGS += \ -DBULK_MEMORY_THRESHOLD=$(BULK_MEMORY_THRESHOLD) -$(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): CFLAGS += \ +$(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS): CFLAGS += \ -D_WASI_EMULATED_SIGNAL +$(OBJDIR)/%.long-double.pic.o: %.c include_dirs + @mkdir -p "$(@D)" + $(CC) $(CFLAGS) -MD -MP -o $@ -c $< + +$(OBJDIR)/%.pic.o: %.c include_dirs + @mkdir -p "$(@D)" + $(CC) $(CFLAGS) -MD -MP -o $@ -c $< + $(OBJDIR)/%.long-double.o: %.c include_dirs @mkdir -p "$(@D)" $(CC) $(CFLAGS) -MD -MP -o $@ -c $< @@ -533,17 +600,17 @@ -include $(shell find $(OBJDIR) -name \*.d) -$(DLMALLOC_OBJS): CFLAGS += \ +$(DLMALLOC_OBJS) $(DLMALLOC_SO_OBJS): CFLAGS += \ -I$(DLMALLOC_INC) -startup_files $(LIBC_BOTTOM_HALF_ALL_OBJS): CFLAGS += \ +startup_files $(LIBC_BOTTOM_HALF_ALL_OBJS) $(LIBC_BOTTOM_HALF_ALL_SO_OBJS): CFLAGS += \ -I$(LIBC_BOTTOM_HALF_HEADERS_PRIVATE) \ -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC) \ -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC) \ -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \ -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal -$(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): CFLAGS += \ +$(LIBC_TOP_HALF_ALL_OBJS) $(LIBC_TOP_HALF_ALL_SO_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS) $(LIBDL_OBJS) $(LIBDL_SO_OBJS): CFLAGS += \ -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \ -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal \ -I$(LIBC_TOP_HALF_MUSL_DIR)/arch/wasm32 \ @@ -557,9 +624,14 @@ -Wno-dangling-else \ -Wno-unknown-pragmas -$(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS): CFLAGS += \ +$(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS) $(LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS): CFLAGS += \ -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC) +# emmalloc uses a lot of pointer type-punning, which is UB under strict aliasing, +# and this was found to have real miscompilations in wasi-libc#421. +$(EMMALLOC_OBJS): CFLAGS += \ + -fno-strict-aliasing + include_dirs: # # Install the include files. @@ -590,6 +662,21 @@ mkdir -p "$(SYSROOT_LIB)" && \ cp $(LIBC_BOTTOM_HALF_CRT_OBJS) "$(SYSROOT_LIB)" +# TODO: As of this writing, wasi_thread_start.s uses non-position-independent +# code, and I'm not sure how to make it position-independent. Once we've done +# that, we can enable libc.so for the wasi-threads build. +ifneq ($(THREAD_MODEL), posix) +LIBC_SO = \ + $(SYSROOT_LIB)/libc.so \ + $(SYSROOT_LIB)/libwasi-emulated-mman.so \ + $(SYSROOT_LIB)/libwasi-emulated-process-clocks.so \ + $(SYSROOT_LIB)/libwasi-emulated-getpid.so \ + $(SYSROOT_LIB)/libwasi-emulated-signal.so \ + $(SYSROOT_LIB)/libdl.so +endif + +libc_so: include_dirs $(LIBC_SO) + libc: include_dirs \ $(SYSROOT_LIB)/libc.a \ $(SYSROOT_LIB)/libc-printscan-long-double.a \ @@ -597,13 +684,14 @@ $(SYSROOT_LIB)/libwasi-emulated-mman.a \ $(SYSROOT_LIB)/libwasi-emulated-process-clocks.a \ $(SYSROOT_LIB)/libwasi-emulated-getpid.a \ - $(SYSROOT_LIB)/libwasi-emulated-signal.a + $(SYSROOT_LIB)/libwasi-emulated-signal.a \ + $(SYSROOT_LIB)/libdl.a finish: startup_files libc # # Create empty placeholder libraries. # - for name in m rt pthread crypt util xnet resolv dl; do \ + for name in m rt pthread crypt util xnet resolv; do \ $(AR) crs "$(SYSROOT_LIB)/lib$${name}.a"; \ done @@ -639,7 +727,7 @@ for undef_sym in $$("$(NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \ |grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \ grep -q '\<'$$undef_sym'\>' "$(DEFINED_SYMBOLS)" || echo $$undef_sym; \ - done | grep -v "^__mul" > "$(UNDEFINED_SYMBOLS)" + done | grep -E -v "^__mul|__memory_base" > "$(UNDEFINED_SYMBOLS)" grep '^_*imported_wasi_' "$(UNDEFINED_SYMBOLS)" \ > "$(SYSROOT_LIB)/libc.imports" @@ -671,6 +759,9 @@ @# @# TODO: Filter out __NO_MATH_ERRNO_ and a few __*WIDTH__ that are new to clang 14. @# TODO: Filter out __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* that are new to clang 16. + @# TODO: Filter out __FPCLASS_* that are new to clang 17. + @# TODO: Filter out __FLT128_* that are new to clang 18. + @# TODO: Filter out __MEMORY_SCOPE_* that are new to clang 18. @# TODO: clang defined __FLT_EVAL_METHOD__ until clang 15, so we force-undefine it @# for older versions. @# TODO: Undefine __wasm_mutable_globals__ and __wasm_sign_ext__, that are new to @@ -702,6 +793,13 @@ | sed -e 's/__GNUC_VA_LIST $$/__GNUC_VA_LIST 1/' \ | grep -v '^#define __\(BOOL\|INT_\(LEAST\|FAST\)\(8\|16\|32\|64\)\|INT\|LONG\|LLONG\|SHRT\)_WIDTH__' \ | grep -v '^#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_\(1\|2\|4\|8\)' \ + | grep -v '^#define __FPCLASS_' \ + | grep -v '^#define __FLT128_' \ + | grep -v '^#define __MEMORY_SCOPE_' \ + | grep -v '^#define NDEBUG' \ + | grep -v '^#define __OPTIMIZE__' \ + | grep -v '^#define assert' \ + | grep -v '^#define __NO_INLINE__' \ > "$(SYSROOT_SHARE)/predefined-macros.txt" # Check that the computed metadata matches the expected metadata. @@ -716,4 +814,4 @@ $(RM) -r "$(OBJDIR)" $(RM) -r "$(SYSROOT)" -.PHONY: default startup_files libc finish install include_dirs clean +.PHONY: default startup_files libc libc_so finish install include_dirs clean check-symbols diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/README.md new/wasi-libc-wasi-sdk-21/README.md --- old/wasi-libc-wasi-sdk-20/README.md 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/README.md 2023-12-15 19:07:28.000000000 +0100 @@ -1,25 +1,27 @@ -# WASI Libc +# `wasi-libc` -WASI Libc is a libc for WebAssembly programs built on top of WASI system calls. -It provides a wide array of POSIX-compatible C APIs, including support for -standard I/O, file I/O, filesystem manipulation, memory management, time, string, -environment variables, program startup, and many other APIs. +`wasi-libc` is a libc for WebAssembly programs built on top of WASI system +calls. It provides a wide array of POSIX-compatible C APIs, including support +for standard I/O, file I/O, filesystem manipulation, memory management, time, +string, environment variables, program startup, and many other APIs. -WASI Libc is sufficiently stable and usable for many purposes, as most of the +`wasi-libc` is sufficiently stable and usable for many purposes, as most of the POSIX-compatible APIs are stable, though it is continuing to evolve to better -align with wasm and WASI. For example, pthread support is still a work in -progress. +align with wasm and WASI. For example, pthread support is experimentally +provided via the [wasi-threads] proposal.` + +[wasi-threads]: https://github.com/WebAssembly/wasi-threads ## Usage The easiest way to get started with this is to use [wasi-sdk], which includes a -build of WASI Libc in its sysroot. +build of `wasi-libc` in its sysroot. ## Building from source To build a WASI sysroot from source, obtain a WebAssembly-supporting C compiler -(currently this is only clang 10+, though we'd like to support other compilers as well), -and then run: +(currently this is only clang 10+, though we'd like to support other compilers +as well), and then run: ```sh make CC=/path/to/clang/with/wasm/support \ @@ -27,7 +29,7 @@ NM=/path/to/llvm-nm ``` -This makes a directory called "sysroot", by default. See the top of the Makefile +This makes a directory called "sysroot" by default. See the top of the Makefile for customization options. To use the sysroot, use the `--sysroot=` option: @@ -39,13 +41,23 @@ to run the compiler using the newly built sysroot. Note that Clang packages typically don't include cross-compiled builds of -compiler-rt, libcxx, or libcxxabi, for `libclang_rt.builtins-wasm32.a`, libc++.a, -or libc++abi.a, respectively, so they may not be usable without +compiler-rt, libcxx, or libcxxabi, for `libclang_rt.builtins-wasm32.a`, +`libc++.a`, or `libc++abi.a`, respectively, so they may not be usable without extra setup. This is one of the things [wasi-sdk] simplifies, as it includes -cross-compiled builds of compiler-rt, libc++.a, and libc++abi.a. +cross-compiled builds of compiler-rt, `libc++.a`, and `libc++abi.a`. + +## Building in pthread support + +To enable pthreads support via the [wasi-threads] proposal, follow the above +build directions with one addition: `make ... THREAD_MODEL=posix`. This creates +additional artifacts in `sysroot/lib/wasm32-wasi-threads` to support `--target +wasm32-wasi-threads`. ## Arch Linux AUR package -For Arch Linux users, there's an unofficial AUR package tracking this git repo that can be installed under the name [wasi-libc-git]. + +For Arch Linux users, there's an official [wasi-libc] package tracking this Git +repository. You might want to install other [WASI related packages] as well. [wasi-sdk]: https://github.com/WebAssembly/wasi-sdk -[wasi-libc-git]: https://aur.archlinux.org/packages/wasi-libc-git/ +[wasi-libc]: https://archlinux.org/packages/extra/any/wasi-libc/ +[WASI related packages]: https://archlinux.org/packages/?q=wasi- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/dlmalloc/src/malloc.c new/wasi-libc-wasi-sdk-21/dlmalloc/src/malloc.c --- old/wasi-libc-wasi-sdk-20/dlmalloc/src/malloc.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/dlmalloc/src/malloc.c 2023-12-15 19:07:28.000000000 +0100 @@ -4593,14 +4593,14 @@ ensure_initialization(); /* initialize in sys_alloc if not using locks */ #endif + if (!PREACTION(gm)) { #if __wasilibc_unmodified_upstream // Try to initialize the allocator. #else - if (!is_initialized(gm)) { - try_init_allocator(); - } + if (!is_initialized(gm)) { + try_init_allocator(); + } #endif - if (!PREACTION(gm)) { void* mem; size_t nb; if (bytes <= MAX_SMALL_REQUEST) { @@ -5215,7 +5215,7 @@ /* Symbol marking the end of data, bss and explicit stack, provided by wasm-ld. */ extern char __heap_base; -extern char __heap_end __attribute__((__weak__)); +extern char __heap_end; /* Initialize the initial state of dlmalloc to be able to use free memory between __heap_base and initial. */ static void try_init_allocator(void) { @@ -5227,23 +5227,18 @@ char *base = &__heap_base; // Try to use the linker pseudo-symbol `__heap_end` for the initial size of - // the heap, but if that's not defined due to LLVM being too old perhaps then - // round up `base` to the nearest `PAGESIZE`. The initial size of linear - // memory will be at least the heap base to this page boundary, and it's then - // assumed that the initial linear memory image was truncated at that point. - // While this reflects the default behavior of `wasm-ld` it is also possible - // for users to craft larger linear memories by passing options to extend - // beyond this threshold. In this situation the memory will not be used for - // dlmalloc. - // - // Note that `sbrk(0)`, or in dlmalloc-ese `CALL_MORECORE(0)`, is specifically - // not used here. That captures the current size of the heap but is only - // correct if the we're the first to try to grow the heap. If the heap has - // grown elsewhere, such as a different allocator in place, then this would - // incorrectly claim such memroy as our own. + // the heap. char *end = &__heap_end; - if (end == NULL) - end = (char*) page_align((size_t) base); + if (end < base) { + // "end" can be NULL when 1. you are using an old wasm-ld which doesn't + // provide `__heap_end` (< 15.0.7) and 2. something (other libraries + // or maybe your app?) includes a weak reference to `__heap_end` and + // 3. the weak reference is found by the linker before this strong + // reference. + // + // Note: This is a linker bug: https://github.com/llvm/llvm-project/issues/60829 + __builtin_trap(); + } size_t initial_heap_size = end - base; /* Check that initial heap is long enough to serve a minimal allocation request. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/defined-symbols.txt new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/defined-symbols.txt --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/defined-symbols.txt 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/defined-symbols.txt 2023-12-15 19:07:28.000000000 +0100 @@ -329,6 +329,7 @@ __wasilibc_nocwd_symlinkat __wasilibc_nocwd_utimensat __wasilibc_open_nomode +__wasilibc_populate_preopens __wasilibc_register_preopened_fd __wasilibc_rename_newat __wasilibc_rename_oldat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/include-all.c new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/include-all.c --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/include-all.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/include-all.c 2023-12-15 19:07:28.000000000 +0100 @@ -75,6 +75,7 @@ #include <crypt.h> #include <ctype.h> #include <dirent.h> +#include <dlfcn.h> #include <endian.h> #include <err.h> #include <errno.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/predefined-macros.txt new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/predefined-macros.txt --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/predefined-macros.txt 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/predefined-macros.txt 2023-12-15 19:07:28.000000000 +0100 @@ -33,10 +33,10 @@ #define ADJ_TAI 0x0080 #define ADJ_TICK 0x4000 #define ADJ_TIMECONST 0x0020 -#define AF_INET 1 -#define AF_INET6 2 +#define AF_INET PF_INET +#define AF_INET6 PF_INET6 #define AF_UNIX 3 -#define AF_UNSPEC 0 +#define AF_UNSPEC PF_UNSPEC #define ALT_DIGITS 0x2002F #define AM_STR 0x20026 #define ANYMARK 0x01 @@ -1119,7 +1119,6 @@ #define NAN (0.0f/0.0f) #define NBBY 8 #define NCARGS 131072 -#define NDEBUG 1 #define ND_NA_FLAG_OVERRIDE 0x00000020 #define ND_NA_FLAG_ROUTER 0x00000080 #define ND_NA_FLAG_SOLICITED 0x00000040 @@ -1316,6 +1315,9 @@ #define PAGE_SIZE PAGESIZE #define PATH_MAX 4096 #define PDP_ENDIAN __PDP_ENDIAN +#define PF_INET 1 +#define PF_INET6 2 +#define PF_UNSPEC 0 #define PM_STR 0x20027 #define POLLERR 0x1000 #define POLLHUP 0x2000 @@ -1465,6 +1467,14 @@ #define RRFIXEDSZ NS_RRFIXEDSZ #define RRQ 01 #define RS_HIPRI 0x01 +#define RTLD_DEFAULT ((void *)0) +#define RTLD_GLOBAL 256 +#define RTLD_LAZY 1 +#define RTLD_LOCAL 8 +#define RTLD_NEXT ((void *)-1) +#define RTLD_NODELETE 4096 +#define RTLD_NOLOAD 4 +#define RTLD_NOW 2 #define RUSAGE_CHILDREN 2 #define RUSAGE_SELF 1 #define R_OK (4) @@ -2008,6 +2018,7 @@ #define _Complex_I (0.0f+1.0fi) #define _DIRENT_H #define _DIRENT_HAVE_D_TYPE +#define _DLFCN_H #define _ENDIAN_H #define _ERRNO_H #define _ERR_H @@ -2648,7 +2659,6 @@ #define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 #define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 #define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 -#define __OPTIMIZE__ 1 #define __ORDER_BIG_ENDIAN__ 4321 #define __ORDER_LITTLE_ENDIAN__ 1234 #define __ORDER_PDP_ENDIAN__ 3412 @@ -3073,7 +3083,6 @@ #define and_eq &= #define asin(x) __tg_real_complex(asin, (x)) #define asinh(x) __tg_real_complex(asinh, (x)) -#define assert(x) (void)0 #define atan(x) __tg_real_complex(atan, (x)) #define atan2(x,y) __tg_real_2(atan2, (x), (y)) #define atanh(x) __tg_real_complex(atanh, (x)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/undefined-symbols.txt new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/undefined-symbols.txt --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi/undefined-symbols.txt 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi/undefined-symbols.txt 2023-12-15 19:07:28.000000000 +0100 @@ -11,6 +11,7 @@ __getf2 __gttf2 __heap_base +__heap_end __imported_wasi_snapshot_preview1_args_get __imported_wasi_snapshot_preview1_args_sizes_get __imported_wasi_snapshot_preview1_clock_res_get @@ -58,7 +59,6 @@ __imported_wasi_snapshot_preview1_sock_shutdown __letf2 __lttf2 -__main_argc_argv __netf2 __stack_pointer __subtf3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/defined-symbols.txt new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/defined-symbols.txt --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/defined-symbols.txt 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/defined-symbols.txt 2023-12-15 19:07:28.000000000 +0100 @@ -390,6 +390,7 @@ __wasilibc_nocwd_symlinkat __wasilibc_nocwd_utimensat __wasilibc_open_nomode +__wasilibc_populate_preopens __wasilibc_pthread_self __wasilibc_register_preopened_fd __wasilibc_rename_newat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/include-all.c new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/include-all.c --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/include-all.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/include-all.c 2023-12-15 19:07:28.000000000 +0100 @@ -75,6 +75,7 @@ #include <crypt.h> #include <ctype.h> #include <dirent.h> +#include <dlfcn.h> #include <endian.h> #include <err.h> #include <errno.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/predefined-macros.txt new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/predefined-macros.txt --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/predefined-macros.txt 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/predefined-macros.txt 2023-12-15 19:07:28.000000000 +0100 @@ -33,10 +33,10 @@ #define ADJ_TAI 0x0080 #define ADJ_TICK 0x4000 #define ADJ_TIMECONST 0x0020 -#define AF_INET 1 -#define AF_INET6 2 +#define AF_INET PF_INET +#define AF_INET6 PF_INET6 #define AF_UNIX 3 -#define AF_UNSPEC 0 +#define AF_UNSPEC PF_UNSPEC #define ALT_DIGITS 0x2002F #define AM_STR 0x20026 #define ANYMARK 0x01 @@ -1119,7 +1119,6 @@ #define NAN (0.0f/0.0f) #define NBBY 8 #define NCARGS 131072 -#define NDEBUG 1 #define ND_NA_FLAG_OVERRIDE 0x00000020 #define ND_NA_FLAG_ROUTER 0x00000080 #define ND_NA_FLAG_SOLICITED 0x00000040 @@ -1316,6 +1315,9 @@ #define PAGE_SIZE PAGESIZE #define PATH_MAX 4096 #define PDP_ENDIAN __PDP_ENDIAN +#define PF_INET 1 +#define PF_INET6 2 +#define PF_UNSPEC 0 #define PM_STR 0x20027 #define POLLERR 0x1000 #define POLLHUP 0x2000 @@ -1497,6 +1499,14 @@ #define RRFIXEDSZ NS_RRFIXEDSZ #define RRQ 01 #define RS_HIPRI 0x01 +#define RTLD_DEFAULT ((void *)0) +#define RTLD_GLOBAL 256 +#define RTLD_LAZY 1 +#define RTLD_LOCAL 8 +#define RTLD_NEXT ((void *)-1) +#define RTLD_NODELETE 4096 +#define RTLD_NOLOAD 4 +#define RTLD_NOW 2 #define RUSAGE_CHILDREN 2 #define RUSAGE_SELF 1 #define R_OK (4) @@ -2042,6 +2052,7 @@ #define _Complex_I (0.0f+1.0fi) #define _DIRENT_H #define _DIRENT_HAVE_D_TYPE +#define _DLFCN_H #define _ENDIAN_H #define _ERRNO_H #define _ERR_H @@ -2685,7 +2696,6 @@ #define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 #define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 #define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 -#define __OPTIMIZE__ 1 #define __ORDER_BIG_ENDIAN__ 4321 #define __ORDER_LITTLE_ENDIAN__ 1234 #define __ORDER_PDP_ENDIAN__ 3412 @@ -3112,7 +3122,6 @@ #define and_eq &= #define asin(x) __tg_real_complex(asin, (x)) #define asinh(x) __tg_real_complex(asinh, (x)) -#define assert(x) (void)0 #define atan(x) __tg_real_complex(atan, (x)) #define atan2(x,y) __tg_real_2(atan2, (x), (y)) #define atanh(x) __tg_real_complex(atanh, (x)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/undefined-symbols.txt new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/undefined-symbols.txt --- old/wasi-libc-wasi-sdk-20/expected/wasm32-wasi-threads/undefined-symbols.txt 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/expected/wasm32-wasi-threads/undefined-symbols.txt 2023-12-15 19:07:28.000000000 +0100 @@ -13,6 +13,7 @@ __global_base __gttf2 __heap_base +__heap_end __imported_wasi_snapshot_preview1_args_get __imported_wasi_snapshot_preview1_args_sizes_get __imported_wasi_snapshot_preview1_clock_res_get @@ -61,7 +62,6 @@ __imported_wasi_thread_spawn __letf2 __lttf2 -__main_argc_argv __netf2 __stack_pointer __subtf3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/cloudlibc/src/libc/unistd/close.c new/wasi-libc-wasi-sdk-21/libc-bottom-half/cloudlibc/src/libc/unistd/close.c --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/cloudlibc/src/libc/unistd/close.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/cloudlibc/src/libc/unistd/close.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,16 +0,0 @@ -// Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ -// -// SPDX-License-Identifier: BSD-2-Clause - -#include <wasi/api.h> -#include <errno.h> -#include <unistd.h> - -int close(int fildes) { - __wasi_errno_t error = __wasi_fd_close(fildes); - if (error != 0) { - errno = error; - return -1; - } - return 0; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/headers/public/__errno.h new/wasi-libc-wasi-sdk-21/libc-bottom-half/headers/public/__errno.h --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/headers/public/__errno.h 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/headers/public/__errno.h 2023-12-15 19:07:28.000000000 +0100 @@ -5,16 +5,11 @@ extern "C" { #endif -#ifdef __cplusplus -extern thread_local int errno; -#else extern _Thread_local int errno; -#endif #define errno errno #ifdef __cplusplus } #endif - #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/headers/public/__header_sys_socket.h new/wasi-libc-wasi-sdk-21/libc-bottom-half/headers/public/__header_sys_socket.h --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/headers/public/__header_sys_socket.h 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/headers/public/__header_sys_socket.h 2023-12-15 19:07:28.000000000 +0100 @@ -25,9 +25,13 @@ #define SO_TYPE 3 -#define AF_UNSPEC 0 -#define AF_INET 1 -#define AF_INET6 2 +#define PF_UNSPEC 0 +#define PF_INET 1 +#define PF_INET6 2 + +#define AF_UNSPEC PF_UNSPEC +#define AF_INET PF_INET +#define AF_INET6 PF_INET6 #define AF_UNIX 3 #ifdef __cplusplus diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/headers/public/wasi/libc.h new/wasi-libc-wasi-sdk-21/libc-bottom-half/headers/public/wasi/libc.h --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/headers/public/wasi/libc.h 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/headers/public/wasi/libc.h 2023-12-15 19:07:28.000000000 +0100 @@ -11,6 +11,12 @@ struct stat; struct timespec; +/// Populate libc's preopen tables. This is normally done automatically +/// just before it's needed, however if you call `__wasi_fd_renumber` or +/// `__wasi_fd_close` directly, and you need the preopens to be accurate +/// afterward, you should call this before doing so. +void __wasilibc_populate_preopens(void); + /// Register the given pre-opened file descriptor under the given path. /// /// This function does not take ownership of `prefix` (it makes its own copy). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/signal/signal.c new/wasi-libc-wasi-sdk-21/libc-bottom-half/signal/signal.c --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/signal/signal.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/signal/signal.c 2023-12-15 19:07:28.000000000 +0100 @@ -30,13 +30,13 @@ _Noreturn static void terminate_handler(int sig) { - fprintf(stderr, "Program recieved termination signal: %s\n", strsignal(sig)); + fprintf(stderr, "Program received termination signal: %s\n", strsignal(sig)); abort(); } _Noreturn static void stop_handler(int sig) { - fprintf(stderr, "Program recieved stop signal: %s\n", strsignal(sig)); + fprintf(stderr, "Program received stop signal: %s\n", strsignal(sig)); abort(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/sources/__main_void.c new/wasi-libc-wasi-sdk-21/libc-bottom-half/sources/__main_void.c --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/sources/__main_void.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/sources/__main_void.c 2023-12-15 19:07:28.000000000 +0100 @@ -3,11 +3,22 @@ #include <sysexits.h> // The user's `main` function, expecting arguments. +// +// Note that we make this a weak symbol so that it will have a +// `WASM_SYM_BINDING_WEAK` flag in libc.so, which tells the dynamic linker that +// it need not be defined (e.g. in reactor-style apps with no main function). +// See also the TODO comment on `__main_void` below. +__attribute__((__weak__)) int __main_argc_argv(int argc, char *argv[]); // If the user's `main` function expects arguments, the compiler will rename // it to `__main_argc_argv`, and this version will get linked in, which // initializes the argument data and calls `__main_argc_argv`. +// +// TODO: Ideally this function would be defined in a crt*.o file and linked in +// as necessary by the Clang driver. However, moving it to crt1-command.c +// breaks `--no-gc-sections`, so we'll probably need to create a new file +// (e.g. crt0.o or crtend.o) and teach Clang to use it when needed. __attribute__((__weak__, nodebug)) int __main_void(void) { __wasi_errno_t err; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/sources/__wasilibc_fd_renumber.c new/wasi-libc-wasi-sdk-21/libc-bottom-half/sources/__wasilibc_fd_renumber.c --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/sources/__wasilibc_fd_renumber.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/sources/__wasilibc_fd_renumber.c 2023-12-15 19:07:28.000000000 +0100 @@ -4,6 +4,9 @@ #include <unistd.h> int __wasilibc_fd_renumber(int fd, int newfd) { + // Scan the preopen fds before making any changes. + __wasilibc_populate_preopens(); + __wasi_errno_t error = __wasi_fd_renumber(fd, newfd); if (error != 0) { errno = error; @@ -11,3 +14,22 @@ } return 0; } + +int close(int fd) { + // Scan the preopen fds before making any changes. + __wasilibc_populate_preopens(); + + __wasi_errno_t error = __wasi_fd_close(fd); + if (error != 0) { + errno = error; + return -1; + } + + return 0; +} + +weak void __wasilibc_populate_preopens(void) { + // This version does nothing. It may be overridden by a version which does + // something if `__wasilibc_find_abspath` or `__wasilibc_find_relpath` are + // used. +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-bottom-half/sources/preopens.c new/wasi-libc-wasi-sdk-21/libc-bottom-half/sources/preopens.c --- old/wasi-libc-wasi-sdk-20/libc-bottom-half/sources/preopens.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-bottom-half/sources/preopens.c 2023-12-15 19:07:28.000000000 +0100 @@ -25,6 +25,7 @@ } preopen; /// A simple growable array of `preopen`. +static _Atomic _Bool preopens_populated = false; static preopen *preopens; static size_t num_preopens; static size_t preopen_capacity; @@ -100,12 +101,9 @@ return path; } -/// Register the given preopened file descriptor under the given path. -/// -/// This function takes ownership of `prefix`. -static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) { - LOCK(lock); - +/// Similar to `internal_register_preopened_fd_unlocked` but does not +/// take a lock. +static int internal_register_preopened_fd_unlocked(__wasi_fd_t fd, const char *relprefix) { // Check preconditions. assert_invariants(); assert(fd != AT_FDCWD); @@ -113,22 +111,32 @@ assert(relprefix != NULL); if (num_preopens == preopen_capacity && resize() != 0) { - UNLOCK(lock); return -1; } char *prefix = strdup(strip_prefixes(relprefix)); if (prefix == NULL) { - UNLOCK(lock); return -1; } preopens[num_preopens++] = (preopen) { prefix, fd, }; assert_invariants(); - UNLOCK(lock); return 0; } +/// Register the given preopened file descriptor under the given path. +/// +/// This function takes ownership of `prefix`. +static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) { + LOCK(lock); + + int r = internal_register_preopened_fd_unlocked(fd, relprefix); + + UNLOCK(lock); + + return r; +} + /// Are the `prefix_len` bytes pointed to by `prefix` a prefix of `path`? static bool prefix_matches(const char *prefix, size_t prefix_len, const char *path) { // Allow an empty string as a prefix of any relative path. @@ -152,6 +160,8 @@ // See the documentation in libc.h int __wasilibc_register_preopened_fd(int fd, const char *prefix) { + __wasilibc_populate_preopens(); + return internal_register_preopened_fd((__wasi_fd_t)fd, prefix); } @@ -172,6 +182,8 @@ int __wasilibc_find_abspath(const char *path, const char **abs_prefix, const char **relative_path) { + __wasilibc_populate_preopens(); + // Strip leading `/` characters, the prefixes we're mataching won't have // them. while (*path == '/') @@ -219,13 +231,20 @@ return fd; } -/// This is referenced by weak reference from crt1.c and lives in the same -/// source file as `__wasilibc_find_relpath` so that it's linked in when it's -/// needed. -// Concerning the 51 -- see the comment by the constructor priority in -// libc-bottom-half/sources/environ.c. -__attribute__((constructor(51))) -static void __wasilibc_populate_preopens(void) { +void __wasilibc_populate_preopens(void) { + // Fast path: If the preopens are already initialized, do nothing. + if (preopens_populated) { + return; + } + + LOCK(lock); + + // Check whether another thread initialized the preopens already. + if (preopens_populated) { + UNLOCK(lock); + return; + } + // Skip stdin, stdout, and stderr, and count up until we reach an invalid // file descriptor. for (__wasi_fd_t fd = 3; fd != 0; ++fd) { @@ -249,7 +268,7 @@ goto oserr; prefix[prestat.u.dir.pr_name_len] = '\0'; - if (internal_register_preopened_fd(fd, prefix) != 0) + if (internal_register_preopened_fd_unlocked(fd, prefix) != 0) goto software; free(prefix); @@ -260,6 +279,11 @@ } } + // Preopens are now initialized. + preopens_populated = true; + + UNLOCK(lock); + return; oserr: _Exit(EX_OSERR); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/include/dlfcn.h new/wasi-libc-wasi-sdk-21/libc-top-half/musl/include/dlfcn.h --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/include/dlfcn.h 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/include/dlfcn.h 2023-12-15 19:07:28.000000000 +0100 @@ -12,19 +12,29 @@ #define RTLD_NOLOAD 4 #define RTLD_NODELETE 4096 #define RTLD_GLOBAL 256 +#ifdef __wasilibc_unmodified_upstream #define RTLD_LOCAL 0 +#else +/* For WASI, we give `RTLD_LOCAL` a non-zero value, avoiding ambiguity and + * allowing us to defer the decision of whether `RTLD_LOCAL` or `RTLD_GLOBAL` + * should be the default when neither is specified. + */ +#define RTLD_LOCAL 8 +#endif #define RTLD_NEXT ((void *)-1) #define RTLD_DEFAULT ((void *)0) +#ifdef __wasilibc_unmodified_upstream #define RTLD_DI_LINKMAP 2 +#endif int dlclose(void *); char *dlerror(void); void *dlopen(const char *, int); void *dlsym(void *__restrict, const char *__restrict); -#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#if defined(__wasilibc_unmodified_upstream) && (defined(_GNU_SOURCE) || defined(_BSD_SOURCE)) typedef struct { const char *dli_fname; void *dli_fbase; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/include/pthread.h new/wasi-libc-wasi-sdk-21/libc-top-half/musl/include/pthread.h --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/include/pthread.h 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/include/pthread.h 2023-12-15 19:07:28.000000000 +0100 @@ -97,7 +97,9 @@ int pthread_setcancelstate(int, int *); int pthread_setcanceltype(int, int *); void pthread_testcancel(void); +#ifdef __wasilibc_unmodified_upstream /* WASI has no cancellation support. */ int pthread_cancel(pthread_t); +#endif #ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */ int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/internal/locale_impl.h new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/internal/locale_impl.h --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/internal/locale_impl.h 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/internal/locale_impl.h 2023-12-15 19:07:28.000000000 +0100 @@ -28,7 +28,15 @@ hidden const struct __locale_map *__get_locale(int, const char *); hidden const char *__mo_lookup(const void *, size_t, const char *); hidden const char *__lctrans(const char *, const struct __locale_map *); +#ifdef __wasilibc_unmodified_upstream hidden const char *__lctrans_cur(const char *); +#else +// We make this visible in the wasi-libc build because +// libwasi-emulated-signal.so needs to import it from libc.so. If we ever +// decide to merge libwasi-emulated-signal.so into libc.so, this will no longer +// be necessary. +const char *__lctrans_cur(const char *); +#endif hidden const char *__lctrans_impl(const char *, const struct __locale_map *); hidden int __loc_is_allocated(locale_t); hidden char *__gettextdomain(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/misc/dl.c new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/misc/dl.c --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/misc/dl.c 1970-01-01 01:00:00.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/misc/dl.c 2023-12-15 19:07:28.000000000 +0100 @@ -0,0 +1,45 @@ +/* This file is used to build libdl.so with stub versions of `dlopen`, `dlsym`, + * etc. The intention is that this stubbed libdl.so can be used to build + * libraries and applications which use `dlopen` without committing to a + * specific runtime implementation. Later, it can be replaced with a real, + * working libdl.so (e.g. at runtime or component composition time). + * + * For example, the `wasm-tools component link` subcommand can be used to create + * a component that bundles any `dlopen`-able libraries in such a way that their + * function exports can be resolved symbolically at runtime using an + * implementation of libdl.so designed for that purpose. In other cases, a + * runtime might provide Emscripten-style dynamic linking via URLs or else a + * more traditional, filesystem-based implementation. Finally, even this + * stubbed version of libdl.so can be used at runtime in cases where dynamic + * library resolution cannot or should not be supported (and the application can + * handle this situation gracefully). */ + +#include <stddef.h> +#include <dlfcn.h> + +static const char *error = NULL; + +weak int dlclose(void *library) +{ + error = "dlclose not implemented"; + return -1; +} + +weak char *dlerror(void) +{ + const char *var = error; + error = NULL; + return (char*) var; +} + +weak void *dlopen(const char *name, int flags) +{ + error = "dlopen not implemented"; + return NULL; +} + +weak void *dlsym(void *library, const char *name) +{ + error = "dlsym not implemented"; + return NULL; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/thread/pthread_create.c new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/thread/pthread_create.c --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/thread/pthread_create.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/thread/pthread_create.c 2023-12-15 19:07:28.000000000 +0100 @@ -13,6 +13,7 @@ #endif #include <stdalign.h> +#include <assert.h> static void dummy_0() { @@ -60,6 +61,17 @@ if (tl_lock_waiters) __wake(&__thread_list_lock, 1, 0); } +#ifndef __wasilibc_unmodified_upstream +static void *map_base_deferred_free; + +static void process_map_base_deferred_free() +{ + /* called with __tl_lock held */ + free(map_base_deferred_free); + map_base_deferred_free = NULL; +} +#endif + #ifdef __wasilibc_unmodified_upstream _Noreturn void __pthread_exit(void *result) #else @@ -164,14 +176,6 @@ self->prev->next = self->next; self->prev = self->next = self; -#ifndef __wasilibc_unmodified_upstream - /* On Linux, the thread is created with CLONE_CHILD_CLEARTID, - * and this lock will unlock by kernel when this thread terminates. - * So we should unlock it here in WebAssembly. - * See also set_tid_address(2) */ - __tl_unlock(); -#endif - #ifdef __wasilibc_unmodified_upstream if (state==DT_DETACHED && self->map_base) { /* Detached threads must block even implementation-internal @@ -190,10 +194,17 @@ } #else if (state==DT_DETACHED && self->map_base) { - // __syscall(SYS_exit) would unlock the thread, list - // do it manually here - __tl_unlock(); - free(self->map_base); + /* As we use malloc/free which is considerably more complex + * than mmap/munmap to call and can even require a valid + * thread context, it's difficult to implement __unmapself. + * + * Here we take an alternative approach which simply defers + * the deallocation. An obvious downside of this approach is + * that it keeps the stack longer. (possibly forever.) + * To avoid wasting too much memory, we only defer a single + * item at most. */ + process_map_base_deferred_free(); + map_base_deferred_free = self->map_base; // Can't use `exit()` here, because it is too high level return; } @@ -212,10 +223,15 @@ #ifdef __wasilibc_unmodified_upstream for (;;) __syscall(SYS_exit, 0); #else - // __syscall(SYS_exit) would unlock the thread, list - // do it manually here - __tl_unlock(); // Can't use `exit()` here, because it is too high level + + /* On Linux, the thread is created with CLONE_CHILD_CLEARTID, + * and the lock (__thread_list_lock) will be unlocked by kernel when + * this thread terminates. + * See also set_tid_address(2) + * + * In WebAssembly, we leave it to wasi_thread_start instead. + */ #endif } @@ -430,6 +446,14 @@ if (map == MAP_FAILED) goto fail; } #else + /* Process the deferred free request if any before + * allocationg a new one. Hopefully it enables a reuse of the memory. + * + * Note: We can't perform a simple "handoff" becasue allocation + * sizes might be different. (eg. the stack size might differ) */ + __tl_lock(); + process_map_base_deferred_free(); + __tl_unlock(); map = malloc(size); if (!map) goto fail; #endif @@ -535,13 +559,17 @@ __wait(&args->control, 0, 3, 0); } #else +#define WASI_THREADS_MAX_TID 0x1FFFFFFF /* `wasi_thread_spawn` will either return a host-provided thread ID (TID) - * (`>= 0`) or an error code (`< 0`). As in the unmodified version, all - * spawn failures translate to EAGAIN; unlike the modified version, there is - * no need to "start up" the child thread--the host does this. If the spawn - * did succeed, then we store the TID atomically, since this parent thread - * is racing with the child thread to set this field; this way, whichever - * thread reaches this point first can continue without waiting. */ + * (`<1, 0x1FFFFFFF>`) or an error code (`< 0`). Please note that `0` is + * reserved for compatibility reasons and must not be returned by the runtime. + * As in the unmodified version, all spawn failures translate to EAGAIN; + * unlike the modified version, there is no need to "start up" the child + * thread--the host does this. If the spawn did succeed, then we store the + * TID atomically, since this parent thread is racing with the child thread + * to set this field; this way, whichever thread reaches this point first + * can continue without waiting. */ + assert(ret != 0 && ret <= WASI_THREADS_MAX_TID); if (ret < 0) { ret = -EAGAIN; } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/thread/pthread_mutex_trylock.c new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/thread/pthread_mutex_trylock.c --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/thread/pthread_mutex_trylock.c 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/thread/pthread_mutex_trylock.c 2023-12-15 19:07:28.000000000 +0100 @@ -21,7 +21,9 @@ return 0; } } +#ifdef __wasilibc_unmodified_upstream if (own == 0x3fffffff) return ENOTRECOVERABLE; +#endif if (own || (old && !(type & 4))) return EBUSY; if (type & 128) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/thread/wasm32/wasi_thread_start.s new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/thread/wasm32/wasi_thread_start.s --- old/wasi-libc-wasi-sdk-20/libc-top-half/musl/src/thread/wasm32/wasi_thread_start.s 2023-03-24 08:34:15.000000000 +0100 +++ new/wasi-libc-wasi-sdk-21/libc-top-half/musl/src/thread/wasm32/wasi_thread_start.s 2023-12-15 19:07:28.000000000 +0100 @@ -28,4 +28,21 @@ local.get 1 # start_arg call __wasi_thread_start_C + # Unlock thread list. (as CLONE_CHILD_CLEARTID would do for Linux) + # + # Note: once we unlock the thread list, our "map_base" can be freed + # by a joining thread. It's safe as we are in ASM and no longer use + # our C stack or pthread_t. It's impossible to do this safely in C + # because there is no way to tell the C compiler not to use C stack. + i32.const __thread_list_lock + i32.const 0 + i32.atomic.store 0 + # As an optimization, we can check tl_lock_waiters here. + # But for now, simply wake up unconditionally as + # CLONE_CHILD_CLEARTID does. + i32.const __thread_list_lock + i32.const 1 + memory.atomic.notify 0 + drop + end_function