diff options
Diffstat (limited to 'lib/mlibc/tests/posix/sigaltstack.c')
-rw-r--r-- | lib/mlibc/tests/posix/sigaltstack.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/mlibc/tests/posix/sigaltstack.c b/lib/mlibc/tests/posix/sigaltstack.c new file mode 100644 index 0000000..bebcc30 --- /dev/null +++ b/lib/mlibc/tests/posix/sigaltstack.c @@ -0,0 +1,55 @@ +#include <assert.h> +#include <setjmp.h> +#include <signal.h> +#include <stdlib.h> + +static jmp_buf env; +static char *sigStack; + +static void sig_handler(int sig, siginfo_t *info, void *ctx) { + (void)sig; + (void)info; + (void)ctx; + + longjmp(env, 1); +} + +int main() { + if (setjmp(env)) { + free(sigStack); + return 0; + } + + sigStack = malloc(SIGSTKSZ); + + stack_t ss; + ss.ss_sp = sigStack; + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + + assert(!sigaltstack(&ss, NULL)); + + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + sa.sa_sigaction = sig_handler; + + assert(!sigaction(SIGSEGV, &sa, NULL)); + + // This is used to trash the stack to ensure sigaltstack actually switched stacks. +#if defined(__x86_64__) + asm volatile ("mov $0, %rsp\n" + "\t" "push $0"); +#elif defined(__i386__) + asm volatile ("mov $0, %esp\n" + "\t" "push $0"); +#elif defined(__aarch64__) + asm volatile ("mov sp, %0\n" + "\t" "stp x0, x1, [sp, #-16]!" :: "r"((uint64_t)0)); +#elif defined(__riscv) && __riscv_xlen == 64 + asm volatile ("li sp, 0\n" + "\t" "sd zero, 0(sp)"); +#else +# error Unknown architecture +#endif +} |