diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 3e77871e0..8af7d6873 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -51,15 +51,22 @@ runs: echo "NM=$CLANG_DIR/llvm-nm" >> $GITHUB_ENV if: runner.os == 'macOS' - # Note that this uses apt-based packages for installing Clang/tools to - # ensure that all various dependencies are also installed. Binaries from - # llvm-project depend on libtinfo.so and TBH I don't know what that is. - # Using apt-get should basically serve the same purpose though. + # Use apt repositories to install various clang versions on Linux as those + # generally work the best and are more available than per-release downloads + # of LLVM. Note that apt.llvm.org may be used for new enough versions of + # clang which aren't in Ubuntu 24.04. - name: Install LLVM tools (Linux) shell: bash run: | set -ex v=${{ inputs.clang_version }} + # For LLVM versions 21+ install from apt.llvm.org because the ubuntu + # 24.04 repositories don't have these binaries. + if [ $v -ge 21 ]; then + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + rel=$(lsb_release -cs) + sudo apt-add-repository "deb http://apt.llvm.org/$rel/ llvm-toolchain-$rel-$v main" + fi sudo apt-get update sudo apt-get install -y clang-$v clang-tools-$v lld-$v echo "CC=clang-$v" >> $GITHUB_ENV diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3503a4fdc..cadb2d356 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -162,6 +162,11 @@ jobs: test: true args: -DTARGET_TRIPLE=wasm32-wasip2 + - name: Test LLVM 22 + os: ubuntu-24.04 + clang_version: 22 + test: true + args: -DTARGET_TRIPLE=wasm32-wasip2 steps: - uses: actions/checkout@v6 with: diff --git a/cmake/scripts/run-check-symbols.cmake b/cmake/scripts/run-check-symbols.cmake index f44cc149f..f66782a06 100644 --- a/cmake/scripts/run-check-symbols.cmake +++ b/cmake/scripts/run-check-symbols.cmake @@ -78,6 +78,7 @@ foreach(symbol IN LISTS final_undefined_symbols) if(NOT symbol MATCHES "^__mul" AND NOT symbol STREQUAL "__memory_base" AND NOT symbol STREQUAL "__indirect_function_table" AND + NOT symbol STREQUAL "__wasm_first_page_end" AND NOT symbol STREQUAL "__tls_base") file(APPEND ${out_undefined_symbols} "${symbol}\n") endif() diff --git a/libc-top-half/musl/src/setjmp/wasm32/rt.c b/libc-top-half/musl/src/setjmp/wasm32/rt.c index 24e4e3361..83fa31077 100644 --- a/libc-top-half/musl/src/setjmp/wasm32/rt.c +++ b/libc-top-half/musl/src/setjmp/wasm32/rt.c @@ -81,3 +81,21 @@ __wasm_longjmp(void *env, int val) arg->val = val; __builtin_wasm_throw(1, arg); /* 1 == C_LONGJMP */ } + +// The `__builtin_wasm_throw` invocation above will reference this symbol which +// refers to a WebAssembly tag. The tag can't be defined in C but we can define +// it with inline assembly, so do so here. +// +// Note that the means of defining this symbol changed historically, so this +// is only done on LLVM 22+ where it's required. +#if __clang_major__ >= 22 +__asm__(".globl __c_longjmp\n" +#if defined(__wasm32__) + ".tagtype __c_longjmp i32\n" +#elif defined(__wasm64__) + ".tagtype __c_longjmp i64\n" +#else +#error "Unsupported Wasm architecture" +#endif + "__c_longjmp:\n"); +#endif