mirror of
https://github.com/wasmerio/wasmer.git
synced 2025-09-04 15:28:26 +00:00
Add WASIX DL tests, switch to wasixcc for wasix tests to get DL support
This commit is contained in:
3
tests/wasix/.gitignore
vendored
3
tests/wasix/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
output*
|
||||
*.webc
|
||||
*.wasm
|
||||
*.wasm
|
||||
*.so
|
@@ -11,9 +11,9 @@ typedef unsigned char bool;
|
||||
|
||||
int main()
|
||||
{
|
||||
const size_t expected_count = 7;
|
||||
const char *expected_entries[] = {".", "..", "main.c", "main.wasm", "main-not-asyncified.wasm", "output", "run.sh"};
|
||||
bool entries_observed[7] = {false};
|
||||
const size_t expected_count = 6;
|
||||
const char *expected_entries[] = {".", "..", "main.c", "main.wasm", "output", "run.sh"};
|
||||
bool entries_observed[6] = {false};
|
||||
|
||||
for (int fd = 3; fd <= 5; fd++)
|
||||
{
|
||||
|
0
tests/wasix/dl-needed/.no-build
Normal file
0
tests/wasix/dl-needed/.no-build
Normal file
4
tests/wasix/dl-needed/main-needed.c
Normal file
4
tests/wasix/dl-needed/main-needed.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int main_needed_func(int x)
|
||||
{
|
||||
return x + 1;
|
||||
}
|
49
tests/wasix/dl-needed/main.c
Normal file
49
tests/wasix/dl-needed/main.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
extern int main_needed_func(int);
|
||||
|
||||
int main()
|
||||
{
|
||||
if (main_needed_func(42) != 43)
|
||||
{
|
||||
fprintf(stderr, "main_needed_func returned unexpected value\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *handle = dlopen("./libside.so", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!handle)
|
||||
{
|
||||
fprintf(stderr, "dlopen failed: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int (*side_func)(int) = dlsym(handle, "side_func");
|
||||
if (!side_func)
|
||||
{
|
||||
fprintf(stderr, "dlsym failed: %s\n", dlerror());
|
||||
dlclose(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// side_func returns (x + 4) * 2
|
||||
int res = side_func(42);
|
||||
if (res != 92)
|
||||
{
|
||||
fprintf(stderr, "side_func returned unexpected value: %d\n", res);
|
||||
dlclose(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dlclose(handle) != 0)
|
||||
{
|
||||
fprintf(stderr, "dlclose failed: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Print something to make sure printf and, by extension, data relocations work.
|
||||
// Do *NOT* remote this.
|
||||
printf("All tests passed successfully!\n");
|
||||
|
||||
return 0;
|
||||
}
|
16
tests/wasix/dl-needed/run.sh
Executable file
16
tests/wasix/dl-needed/run.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export WASIXCC_WASM_EXCEPTIONS=yes
|
||||
export WASIXCC_PIC=yes
|
||||
|
||||
# main module and its needed side
|
||||
wasixcc main-needed.c -o libmain-needed.so -Wl,-shared
|
||||
wasixcc main.c libmain-needed.so -o main.wasm -Wl,-pie -Wl,-rpath,\$ORIGIN
|
||||
|
||||
# dlopen'ed side module and its needed side
|
||||
wasixcc side-needed.c -o libside-needed.so -Wl,-shared
|
||||
wasixcc side.c libside-needed.so -o libside.so -Wl,-shared -Wl,-rpath,\$ORIGIN
|
||||
|
||||
$WASMER -q run main.wasm --dir=.
|
4
tests/wasix/dl-needed/side-needed.c
Normal file
4
tests/wasix/dl-needed/side-needed.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int side_needed_func(int x)
|
||||
{
|
||||
return x + 4;
|
||||
}
|
6
tests/wasix/dl-needed/side.c
Normal file
6
tests/wasix/dl-needed/side.c
Normal file
@@ -0,0 +1,6 @@
|
||||
extern int side_needed_func(int);
|
||||
|
||||
int side_func(int x)
|
||||
{
|
||||
return side_needed_func(x) * 2;
|
||||
}
|
0
tests/wasix/dl-tls/.no-build
Normal file
0
tests/wasix/dl-tls/.no-build
Normal file
3
tests/wasix/dl-tls/common.c
Normal file
3
tests/wasix/dl-tls/common.c
Normal file
@@ -0,0 +1,3 @@
|
||||
int tls_base[4] = {0, 0, 0, 0};
|
||||
|
||||
_Thread_local int tls_var = 0;
|
135
tests/wasix/dl-tls/main.c
Normal file
135
tests/wasix/dl-tls/main.c
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
|
||||
extern int side_func(int in_thread, int value);
|
||||
|
||||
bool all_unequal(int *arr, size_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
for (size_t j = i + 1; j < size; j++)
|
||||
{
|
||||
if (arr[i] == arr[j])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Common storage where all functions can store data for the final check
|
||||
// Indices are: main-main, main-side, thread-main, thread-side
|
||||
extern int tls_base[4];
|
||||
|
||||
// TLS variable that should be shared between main and side, but be
|
||||
// different in the thread
|
||||
extern _Thread_local int tls_var;
|
||||
|
||||
// A simple global integer with a TLS pointer
|
||||
int static_int = 1;
|
||||
_Thread_local int *tls_ptr = &static_int;
|
||||
|
||||
void *thread_func(void *arg)
|
||||
{
|
||||
tls_base[2] = (int)__builtin_wasm_tls_base();
|
||||
|
||||
if (tls_ptr != &static_int)
|
||||
{
|
||||
fprintf(stderr, "TLS pointer does not point to static_int\n");
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
if (tls_var != 0)
|
||||
{
|
||||
fprintf(stderr, "TLS variable should initially be 0 in thread, got %d\n", tls_var);
|
||||
return (void *)1;
|
||||
}
|
||||
tls_var = 50;
|
||||
if (side_func(1, 100) != 0)
|
||||
{
|
||||
fprintf(stderr, "side_func failed in thread\n");
|
||||
return (void *)1;
|
||||
}
|
||||
if (tls_var != 100)
|
||||
{
|
||||
fprintf(stderr, "TLS variable not set correctly in thread's side, expected 100, got %d\n", tls_var);
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
int do_main_tests()
|
||||
{
|
||||
tls_base[0] = (int)__builtin_wasm_tls_base();
|
||||
|
||||
// Test if tls_ptr gets set correctly in __wasm_apply_tls_relocs,
|
||||
// repeated in the thread and the side module as well
|
||||
if (tls_ptr != &static_int)
|
||||
{
|
||||
fprintf(stderr, "TLS pointer does not point to static_int\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test that the side module gets the correct address for main's TLS vars
|
||||
// from the linker, repeated in the thread as well
|
||||
if (tls_var != 0)
|
||||
{
|
||||
fprintf(stderr, "TLS variable should initially be 0 in main, got %d\n", tls_var);
|
||||
return 1;
|
||||
}
|
||||
tls_var = 20;
|
||||
if (side_func(0, 40) != 0)
|
||||
{
|
||||
fprintf(stderr, "side_func failed in main\n");
|
||||
return 1;
|
||||
}
|
||||
if (tls_var != 40)
|
||||
{
|
||||
fprintf(stderr, "TLS variable not set correctly in main's side, expected 40, got %d\n", tls_var);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pthread_t thread;
|
||||
if (pthread_create(&thread, NULL, thread_func, NULL) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to create thread\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (do_main_tests())
|
||||
{
|
||||
fprintf(stderr, "Main tests failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *thread_ret;
|
||||
if (pthread_join(thread, &thread_ret) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to join thread\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((int)thread_ret != 0)
|
||||
{
|
||||
fprintf(stderr, "Thread function failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Make sure each instance got a different TLS base
|
||||
if (!all_unequal(tls_base, 4))
|
||||
{
|
||||
fprintf(stderr, "TLS bases are not unique\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
11
tests/wasix/dl-tls/run.sh
Executable file
11
tests/wasix/dl-tls/run.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export WASIXCC_WASM_EXCEPTIONS=yes
|
||||
export WASIXCC_PIC=yes
|
||||
wasixcc common.c -o libcommon.so -Wl,-shared
|
||||
wasixcc side.c libcommon.so -o libside.so -Wl,-shared -Wl,-rpath,\$ORIGIN
|
||||
wasixcc main.c libside.so libcommon.so -o main.wasm -Wl,-pie -Wl,-rpath,\$ORIGIN
|
||||
|
||||
$WASMER -q run main.wasm --dir=.
|
21
tests/wasix/dl-tls/side.c
Normal file
21
tests/wasix/dl-tls/side.c
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern int tls_base[4];
|
||||
|
||||
int side_static_int = 1;
|
||||
_Thread_local int *side_tls_ptr = &side_static_int;
|
||||
|
||||
_Thread_local extern int tls_var;
|
||||
|
||||
int side_func(int in_thread, int value)
|
||||
{
|
||||
if (side_tls_ptr != &side_static_int)
|
||||
{
|
||||
fprintf(stderr, "TLS pointer does not point to static_int\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
tls_base[in_thread ? 1 : 3] = (int)__builtin_wasm_tls_base();
|
||||
tls_var = value;
|
||||
return 0;
|
||||
}
|
0
tests/wasix/dlopen/.no-build
Normal file
0
tests/wasix/dlopen/.no-build
Normal file
53
tests/wasix/dlopen/main.c
Normal file
53
tests/wasix/dlopen/main.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
void *handle = dlopen("./libside.so", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!handle)
|
||||
{
|
||||
fprintf(stderr, "dlopen failed: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int (*side_func)(int) = dlsym(handle, "side_func");
|
||||
if (!side_func)
|
||||
{
|
||||
fprintf(stderr, "dlsym failed: %s\n", dlerror());
|
||||
dlclose(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int res = side_func(42);
|
||||
if (res != 84)
|
||||
{
|
||||
fprintf(stderr, "side_func returned unexpected value: %d\n", res);
|
||||
dlclose(handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dlclose(handle) != 0)
|
||||
{
|
||||
fprintf(stderr, "dlclose failed: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dlclose((void *)0xffffff) == 0)
|
||||
{
|
||||
fprintf(stderr, "expected dlclose to fail for bad handle\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *error = dlerror();
|
||||
if (!error || *error == '\0')
|
||||
{
|
||||
fprintf(stderr, "dlerror should not be empty after bad dlclose\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Print something to make sure printf and, by extension, data relocations work.
|
||||
// Do *NOT* remote this.
|
||||
printf("All tests passed successfully!\n");
|
||||
|
||||
return 0;
|
||||
}
|
10
tests/wasix/dlopen/run.sh
Executable file
10
tests/wasix/dlopen/run.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export WASIXCC_WASM_EXCEPTIONS=yes
|
||||
export WASIXCC_PIC=yes
|
||||
wasixcc main.c -o main.wasm -Wl,-pie
|
||||
wasixcc side.c -o libside.so -Wl,-shared
|
||||
|
||||
$WASMER -q run main.wasm --dir=.
|
4
tests/wasix/dlopen/side.c
Normal file
4
tests/wasix/dlopen/side.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int side_func(int x)
|
||||
{
|
||||
return x * 2;
|
||||
}
|
0
tests/wasix/posix_spawn/.no-build
Normal file
0
tests/wasix/posix_spawn/.no-build
Normal file
@@ -1,5 +1,8 @@
|
||||
set -e
|
||||
|
||||
wasixcc -sRUN_WASM_OPT=no main.c -o main-not-asyncified.wasm
|
||||
wasm-opt --asyncify main-not-asyncified.wasm -o main.wasm
|
||||
|
||||
rm -f output.yyy output.zzz
|
||||
|
||||
# Run the not-asyncified variant to make sure posix_spawn doesn't require asyncify
|
||||
|
@@ -1,72 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -z "${WASI_SDK}" ]]; then
|
||||
echo "WASI_SDK is not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${WASIX_SYSROOT}" ]]; then
|
||||
echo "WASIX_SYSROOT is not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export RANLIB="$WASI_SDK/bin/ranlib"
|
||||
export AR="$WASI_SDK/bin/ar"
|
||||
export NM="$WASI_SDK/bin/nm"
|
||||
export CC="$WASI_SDK/bin/clang"
|
||||
export CXX="$WASI_SDK/bin/clang"
|
||||
export CFLAGS="\
|
||||
--sysroot=$WASIX_SYSROOT \
|
||||
--target=wasm32-wasi \
|
||||
-matomics \
|
||||
-mbulk-memory \
|
||||
-mmutable-globals \
|
||||
-pthread \
|
||||
-mthread-model posix \
|
||||
-ftls-model=local-exec \
|
||||
-fno-trapping-math \
|
||||
-D_WASI_EMULATED_MMAN \
|
||||
-D_WASI_EMULATED_SIGNAL \
|
||||
-D_WASI_EMULATED_PROCESS_CLOCKS \
|
||||
-O3 \
|
||||
-g \
|
||||
-flto"
|
||||
export LD="$WASI_SDK/bin/wasm-ld"
|
||||
export LDFLAGS="\
|
||||
-Wl,--shared-memory \
|
||||
-Wl,--max-memory=4294967296 \
|
||||
-Wl,--import-memory \
|
||||
-Wl,--export-dynamic \
|
||||
-Wl,--export=__heap_base \
|
||||
-Wl,--export=__stack_pointer \
|
||||
-Wl,--export=__data_end \
|
||||
-Wl,--export=__wasm_init_tls \
|
||||
-Wl,--export=__wasm_signal \
|
||||
-Wl,--export=__tls_size \
|
||||
-Wl,--export=__tls_align \
|
||||
-Wl,--export=__tls_base \
|
||||
-lwasi-emulated-mman \
|
||||
-O3 \
|
||||
-g \
|
||||
-flto"
|
||||
export LIBS="\
|
||||
-Wl,--shared-memory \
|
||||
-Wl,--max-memory=4294967296 \
|
||||
-Wl,--import-memory \
|
||||
-Wl,--export-dynamic \
|
||||
-Wl,--export=__heap_base \
|
||||
-Wl,--export=__stack_pointer \
|
||||
-Wl,--export=__data_end \
|
||||
-Wl,--export=__wasm_init_tls \
|
||||
-Wl,--export=__wasm_signal \
|
||||
-Wl,--export=__tls_size \
|
||||
-Wl,--export=__tls_align \
|
||||
-Wl,--export=__tls_base \
|
||||
-lwasi-emulated-mman \
|
||||
-O3 \
|
||||
-g \
|
||||
-flto"
|
||||
|
||||
export WASMER=$(realpath "../../target/release/wasmer")
|
||||
|
||||
printf "\n\nStarting WASIX Test Suite:\n"
|
||||
@@ -76,10 +9,14 @@ while read dir; do
|
||||
dir=$(basename "$dir")
|
||||
printf "Testing $dir..."
|
||||
|
||||
cmd="cd $dir; \
|
||||
$CC $CFLAGS $LDFLAGS -o main-not-asyncified.wasm main.c; \
|
||||
wasm-opt --asyncify main-not-asyncified.wasm -o main.wasm; \
|
||||
./run.sh"
|
||||
if [ -e "$dir/.no-build" ]; then
|
||||
cmd="cd $dir; \
|
||||
./run.sh"
|
||||
else
|
||||
cmd="cd $dir; \
|
||||
wasixcc main.c -o main.wasm; \
|
||||
./run.sh"
|
||||
fi
|
||||
|
||||
if bash -c "$cmd"; then
|
||||
printf "\rTesting $dir ✅\n"
|
||||
|
Reference in New Issue
Block a user