diff options
Diffstat (limited to 'wasm2c')
-rw-r--r-- | wasm2c/examples/fac/fac.c | 2 | ||||
-rw-r--r-- | wasm2c/wasm-rt-impl.c | 107 | ||||
-rw-r--r-- | wasm2c/wasm-rt-impl.h | 2 | ||||
-rw-r--r-- | wasm2c/wasm-rt.h | 48 |
4 files changed, 92 insertions, 67 deletions
diff --git a/wasm2c/examples/fac/fac.c b/wasm2c/examples/fac/fac.c index 33151cdd..bd4ccb58 100644 --- a/wasm2c/examples/fac/fac.c +++ b/wasm2c/examples/fac/fac.c @@ -20,7 +20,7 @@ #define TRAP(x) (wasm_rt_trap(WASM_RT_TRAP_##x), 0) -#if WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_DEPTH_COUNT #define FUNC_PROLOGUE \ if (++wasm_rt_call_stack_depth > WASM_RT_MAX_CALL_STACK_DEPTH) \ TRAP(EXHAUSTION); diff --git a/wasm2c/wasm-rt-impl.c b/wasm2c/wasm-rt-impl.c index 5f22d3bf..09a28726 100644 --- a/wasm2c/wasm-rt-impl.c +++ b/wasm2c/wasm-rt-impl.c @@ -25,8 +25,7 @@ #include <stdlib.h> #include <string.h> -#if (WASM_RT_INSTALL_SIGNAL_HANDLER || !WASM_RT_USE_STACK_DEPTH_COUNT) && \ - !defined(_WIN32) +#if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32) #include <signal.h> #include <unistd.h> #endif @@ -39,6 +38,12 @@ #define PAGE_SIZE 65536 +#ifndef NDEBUG +#define DEBUG_PRINTF(...) fprintf(stderr, __VA_ARGS__); +#else +#define DEBUG_PRINTF(...) +#endif + #if WASM_RT_INSTALL_SIGNAL_HANDLER static bool g_signal_handler_installed = false; #ifdef _WIN32 @@ -46,10 +51,10 @@ static void* g_sig_handler_handle = 0; #endif #endif -#if WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_DEPTH_COUNT WASM_RT_THREAD_LOCAL uint32_t wasm_rt_call_stack_depth; WASM_RT_THREAD_LOCAL uint32_t wasm_rt_saved_call_stack_depth; -#elif WASM_RT_INSTALL_SIGNAL_HANDLER +#elif WASM_RT_STACK_EXHAUSTION_HANDLER static WASM_RT_THREAD_LOCAL void* g_alt_stack = NULL; #endif @@ -65,7 +70,7 @@ extern void WASM_RT_GROW_FAILED_HANDLER(); void wasm_rt_trap(wasm_rt_trap_t code) { assert(code != WASM_RT_TRAP_NONE); -#if WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_DEPTH_COUNT wasm_rt_call_stack_depth = wasm_rt_saved_call_stack_depth; #endif @@ -164,7 +169,45 @@ static void os_print_last_error(const char* msg) { perror(msg); } -#if !WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_INSTALL_SIGNAL_HANDLER +static void os_signal_handler(int sig, siginfo_t* si, void* unused) { + if (si->si_code == SEGV_ACCERR) { + wasm_rt_trap(WASM_RT_TRAP_OOB); + } else { + wasm_rt_trap(WASM_RT_TRAP_EXHAUSTION); + } +} + +static void os_install_signal_handler(void) { + struct sigaction sa; + memset(&sa, '\0', sizeof(sa)); + sa.sa_flags = SA_SIGINFO; +#if WASM_RT_STACK_EXHAUSTION_HANDLER + sa.sa_flags |= SA_ONSTACK; +#endif + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = os_signal_handler; + + /* Install SIGSEGV and SIGBUS handlers, since macOS seems to use SIGBUS. */ + if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL) != 0) { + perror("sigaction failed"); + abort(); + } +} + +static void os_cleanup_signal_handler(void) { + /* Undo what was done in os_install_signal_handler */ + struct sigaction sa; + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = SIG_DFL; + if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL)) { + perror("sigaction failed"); + abort(); + } +} +#endif + +#if WASM_RT_STACK_EXHAUSTION_HANDLER static bool os_has_altstack_installed() { /* check for altstack already in place */ stack_t ss; @@ -175,18 +218,7 @@ static bool os_has_altstack_installed() { return !(ss.ss_flags & SS_DISABLE); } -#endif - -#if WASM_RT_INSTALL_SIGNAL_HANDLER -static void os_signal_handler(int sig, siginfo_t* si, void* unused) { - if (si->si_code == SEGV_ACCERR) { - wasm_rt_trap(WASM_RT_TRAP_OOB); - } else { - wasm_rt_trap(WASM_RT_TRAP_EXHAUSTION); - } -} -#if !WASM_RT_USE_STACK_DEPTH_COUNT /* These routines set up an altstack to handle SIGSEGV from stack overflow. */ static void os_allocate_and_install_altstack(void) { /* verify altstack not already allocated */ @@ -229,10 +261,8 @@ static void os_disable_and_deallocate_altstack(void) { if ((!g_alt_stack) || (ss.ss_flags & SS_DISABLE) || (ss.ss_sp != g_alt_stack) || (ss.ss_size != SIGSTKSZ)) { -#ifndef NDEBUG - fprintf(stderr, - "wasm-rt warning: alternate stack was modified unexpectedly\n"); -#endif + DEBUG_PRINTF( + "wasm-rt warning: alternate stack was modified unexpectedly\n"); return; } @@ -247,35 +277,6 @@ static void os_disable_and_deallocate_altstack(void) { } #endif -static void os_install_signal_handler(void) { - struct sigaction sa; - memset(&sa, '\0', sizeof(sa)); - sa.sa_flags = SA_SIGINFO; -#if !WASM_RT_USE_STACK_DEPTH_COUNT - sa.sa_flags |= SA_ONSTACK; -#endif - sigemptyset(&sa.sa_mask); - sa.sa_sigaction = os_signal_handler; - - /* Install SIGSEGV and SIGBUS handlers, since macOS seems to use SIGBUS. */ - if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL) != 0) { - perror("sigaction failed"); - abort(); - } -} - -static void os_cleanup_signal_handler(void) { - /* Undo what was done in os_install_signal_handler */ - struct sigaction sa; - memset(&sa, '\0', sizeof(sa)); - sa.sa_handler = SIG_DFL; - if (sigaction(SIGSEGV, &sa, NULL) != 0 || sigaction(SIGBUS, &sa, NULL)) { - perror("sigaction failed"); - abort(); - } -} -#endif - #endif void wasm_rt_init(void) { @@ -290,7 +291,7 @@ void wasm_rt_init(void) { } bool wasm_rt_is_initialized(void) { -#if !WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_EXHAUSTION_HANDLER if (!os_has_altstack_installed()) { return false; } @@ -312,13 +313,13 @@ void wasm_rt_free(void) { } void wasm_rt_init_thread(void) { -#if WASM_RT_INSTALL_SIGNAL_HANDLER && !WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_EXHAUSTION_HANDLER os_allocate_and_install_altstack(); #endif } void wasm_rt_free_thread(void) { -#if WASM_RT_INSTALL_SIGNAL_HANDLER && !WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_EXHAUSTION_HANDLER os_disable_and_deallocate_altstack(); #endif } diff --git a/wasm2c/wasm-rt-impl.h b/wasm2c/wasm-rt-impl.h index c7d7fdbf..aa6f46d9 100644 --- a/wasm2c/wasm-rt-impl.h +++ b/wasm2c/wasm-rt-impl.h @@ -30,7 +30,7 @@ extern "C" { /** A setjmp buffer used for handling traps. */ extern WASM_RT_THREAD_LOCAL wasm_rt_jmp_buf g_wasm_rt_jmp_buf; -#if WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_DEPTH_COUNT /** Saved call stack depth that will be restored in case a trap occurs. */ extern WASM_RT_THREAD_LOCAL uint32_t wasm_rt_saved_call_stack_depth; #define WASM_RT_SAVE_STACK_DEPTH() \ diff --git a/wasm2c/wasm-rt.h b/wasm2c/wasm-rt.h index fe68aa1d..55b3cce8 100644 --- a/wasm2c/wasm-rt.h +++ b/wasm2c/wasm-rt.h @@ -166,17 +166,42 @@ extern "C" { #define WASM_RT_INSTALL_SIGNAL_HANDLER 0 #endif -#ifndef WASM_RT_USE_STACK_DEPTH_COUNT -/* The signal handler on POSIX can detect call stack overflows. On windows, or - * platforms without a signal handler, we use stack depth counting. */ +/* We need to detect and trap stack overflows. If we use a signal handler on + * POSIX systems, this can detect call stack overflows. On windows, or platforms + * without a signal handler, we use stack depth counting. */ +#if !defined(WASM_RT_STACK_DEPTH_COUNT) && \ + !defined(WASM_RT_STACK_EXHAUSTION_HANDLER) + #if WASM_RT_INSTALL_SIGNAL_HANDLER && !defined(_WIN32) -#define WASM_RT_USE_STACK_DEPTH_COUNT 0 +#define WASM_RT_STACK_EXHAUSTION_HANDLER 1 #else -#define WASM_RT_USE_STACK_DEPTH_COUNT 1 +#define WASM_RT_STACK_DEPTH_COUNT 1 +#endif + +#endif + +// Ensure the stack macros are defined +#ifndef WASM_RT_STACK_DEPTH_COUNT +#define WASM_RT_STACK_DEPTH_COUNT 0 +#endif +#ifndef WASM_RT_STACK_EXHAUSTION_HANDLER +#define WASM_RT_STACK_EXHAUSTION_HANDLER 0 #endif + +#if (WASM_RT_STACK_EXHAUSTION_HANDLER + WASM_RT_STACK_DEPTH_COUNT) > 1 +#error \ + "Cannot specify multiple options from WASM_RT_STACK_EXHAUSTION_HANDLER , WASM_RT_STACK_DEPTH_COUNT" +#elif (WASM_RT_STACK_EXHAUSTION_HANDLER + WASM_RT_STACK_DEPTH_COUNT) == 0 +#error \ + "Must specify one of WASM_RT_STACK_EXHAUSTION_HANDLER , WASM_RT_STACK_DEPTH_COUNT" +#endif + +#if WASM_RT_STACK_EXHAUSTION_HANDLER && !WASM_RT_INSTALL_SIGNAL_HANDLER +#error \ + "WASM_RT_STACK_EXHAUSTION_HANDLER can only be used if WASM_RT_INSTALL_SIGNAL_HANDLER is enabled" #endif -#if WASM_RT_USE_STACK_DEPTH_COUNT +#if WASM_RT_STACK_DEPTH_COUNT /** * When the signal handler cannot be used to detect stack overflows, stack depth * is limited explicitly. The maximum stack depth before trapping can be @@ -202,7 +227,7 @@ extern WASM_RT_THREAD_LOCAL uint32_t wasm_rt_call_stack_depth; #define WASM_RT_NO_RETURN __attribute__((noreturn)) #endif -#if defined(__APPLE__) && !WASM_RT_USE_STACK_DEPTH_COUNT +#if defined(__APPLE__) && WASM_RT_STACK_EXHAUSTION_HANDLER #define WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS 1 #else #define WASM_RT_MERGED_OOB_AND_EXHAUSTION_TRAPS 0 @@ -279,7 +304,8 @@ typedef struct { } wasm_rt_funcref_t; /** Default (null) value of a funcref */ -#define wasm_rt_funcref_null_value ((wasm_rt_funcref_t){NULL, NULL, {NULL}, NULL}) +#define wasm_rt_funcref_null_value \ + ((wasm_rt_funcref_t){NULL, NULL, {NULL}, NULL}) /** The type of an external reference (opaque to WebAssembly). */ typedef void* wasm_rt_externref_t; @@ -354,8 +380,7 @@ typedef struct { jmp_buf buffer; } wasm_rt_jmp_buf; -#if (WASM_RT_INSTALL_SIGNAL_HANDLER || (!WASM_RT_USE_STACK_DEPTH_COUNT)) && \ - !defined(_WIN32) +#ifndef _WIN32 #define WASM_RT_SETJMP_SETBUF(buf) sigsetjmp(buf, 1) #else #define WASM_RT_SETJMP_SETBUF(buf) setjmp(buf) @@ -364,8 +389,7 @@ typedef struct { #define WASM_RT_SETJMP(buf) \ ((buf).initialized = true, WASM_RT_SETJMP_SETBUF((buf).buffer)) -#if (WASM_RT_INSTALL_SIGNAL_HANDLER || (!WASM_RT_USE_STACK_DEPTH_COUNT)) && \ - !defined(_WIN32) +#ifndef _WIN32 #define WASM_RT_LONGJMP_UNCHECKED(buf, val) siglongjmp(buf, val) #else #define WASM_RT_LONGJMP_UNCHECKED(buf, val) longjmp(buf, val) |