diff options
-rw-r--r-- | .github/workflows/main.yml | 34 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README.md | 39 | ||||
-rw-r--r-- | dlmalloc/src/malloc.c | 37 | ||||
-rw-r--r-- | expected/wasm32-wasi-threads/predefined-macros.txt | 9 | ||||
-rw-r--r-- | expected/wasm32-wasi-threads/undefined-symbols.txt | 1 | ||||
-rw-r--r-- | expected/wasm32-wasi/predefined-macros.txt | 9 | ||||
-rw-r--r-- | expected/wasm32-wasi/undefined-symbols.txt | 1 | ||||
-rw-r--r-- | libc-bottom-half/headers/public/__header_sys_socket.h | 10 | ||||
-rw-r--r-- | libc-top-half/musl/src/thread/pthread_mutex_trylock.c | 2 |
10 files changed, 95 insertions, 52 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 83c2751..eb9b59f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,8 +8,26 @@ jobs: 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 @@ jobs: - 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 @@ jobs: - 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 @@ jobs: 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 @@ -561,6 +561,11 @@ $(LIBC_TOP_HALF_ALL_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_NO $(LIBWASI_EMULATED_PROCESS_CLOCKS_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. @@ -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 @@ make CC=/path/to/clang/with/wasm/support \ 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,10 +41,17 @@ To use the sysroot, use the `--sysroot=` option: 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 diff --git a/dlmalloc/src/malloc.c b/dlmalloc/src/malloc.c index c9c8ea6..9fdfd8f 100644 --- a/dlmalloc/src/malloc.c +++ b/dlmalloc/src/malloc.c @@ -4593,14 +4593,14 @@ void* dlmalloc(size_t bytes) { 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 @@ static void internal_inspect_all(mstate m, /* 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 @@ static void try_init_allocator(void) { 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 --git a/expected/wasm32-wasi-threads/predefined-macros.txt b/expected/wasm32-wasi-threads/predefined-macros.txt index 0fca3e4..820f849 100644 --- a/expected/wasm32-wasi-threads/predefined-macros.txt +++ b/expected/wasm32-wasi-threads/predefined-macros.txt @@ -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 @@ -1315,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 diff --git a/expected/wasm32-wasi-threads/undefined-symbols.txt b/expected/wasm32-wasi-threads/undefined-symbols.txt index a685151..c04b5f7 100644 --- a/expected/wasm32-wasi-threads/undefined-symbols.txt +++ b/expected/wasm32-wasi-threads/undefined-symbols.txt @@ -13,6 +13,7 @@ __getf2 __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 diff --git a/expected/wasm32-wasi/predefined-macros.txt b/expected/wasm32-wasi/predefined-macros.txt index d6cae22..2f2ca8f 100644 --- a/expected/wasm32-wasi/predefined-macros.txt +++ b/expected/wasm32-wasi/predefined-macros.txt @@ -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 @@ -1315,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 diff --git a/expected/wasm32-wasi/undefined-symbols.txt b/expected/wasm32-wasi/undefined-symbols.txt index b9cdb34..6d3b2b7 100644 --- a/expected/wasm32-wasi/undefined-symbols.txt +++ b/expected/wasm32-wasi/undefined-symbols.txt @@ -11,6 +11,7 @@ __floatunsitf __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 diff --git a/libc-bottom-half/headers/public/__header_sys_socket.h b/libc-bottom-half/headers/public/__header_sys_socket.h index 77aaa1b..8ba4eff 100644 --- a/libc-bottom-half/headers/public/__header_sys_socket.h +++ b/libc-bottom-half/headers/public/__header_sys_socket.h @@ -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 --git a/libc-top-half/musl/src/thread/pthread_mutex_trylock.c b/libc-top-half/musl/src/thread/pthread_mutex_trylock.c index c60b45f..2b06507 100644 --- a/libc-top-half/musl/src/thread/pthread_mutex_trylock.c +++ b/libc-top-half/musl/src/thread/pthread_mutex_trylock.c @@ -21,7 +21,9 @@ int __pthread_mutex_trylock_owner(pthread_mutex_t *m) return 0; } } +#ifdef __wasilibc_unmodified_upstream if (own == 0x3fffffff) return ENOTRECOVERABLE; +#endif if (own || (old && !(type & 4))) return EBUSY; if (type & 128) { |