134ff174f3cef6e6058385c0a404572d5e8e5c67cdejanj/* 280e5c17a2a2832793a2d4962fa8264025641e47epetarj Check that a fault signal handler gets the expected info 380e5c17a2a2832793a2d4962fa8264025641e47epetarj */ 480e5c17a2a2832793a2d4962fa8264025641e47epetarj#include <signal.h> 580e5c17a2a2832793a2d4962fa8264025641e47epetarj#include <stdio.h> 680e5c17a2a2832793a2d4962fa8264025641e47epetarj#include <stdlib.h> 780e5c17a2a2832793a2d4962fa8264025641e47epetarj#include <fcntl.h> 880e5c17a2a2832793a2d4962fa8264025641e47epetarj#include <setjmp.h> 980e5c17a2a2832793a2d4962fa8264025641e47epetarj#include <unistd.h> 1080e5c17a2a2832793a2d4962fa8264025641e47epetarj 1180e5c17a2a2832793a2d4962fa8264025641e47epetarjstruct test { 1280e5c17a2a2832793a2d4962fa8264025641e47epetarj void (*test)(void); 1380e5c17a2a2832793a2d4962fa8264025641e47epetarj int sig; 1480e5c17a2a2832793a2d4962fa8264025641e47epetarj int code; 1580e5c17a2a2832793a2d4962fa8264025641e47epetarj}; 1680e5c17a2a2832793a2d4962fa8264025641e47epetarj 1780e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic const struct test *curr_test; 1880e5c17a2a2832793a2d4962fa8264025641e47epetarj 1980e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic jmp_buf escape; 2080e5c17a2a2832793a2d4962fa8264025641e47epetarj 2180e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic int testsig(int sig, int want) 2280e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 2380e5c17a2a2832793a2d4962fa8264025641e47epetarj if (sig != want) { 2480e5c17a2a2832793a2d4962fa8264025641e47epetarj fprintf(stderr, " FAIL: expected signal %d, not %d\n", want, sig); 2580e5c17a2a2832793a2d4962fa8264025641e47epetarj return 0; 2680e5c17a2a2832793a2d4962fa8264025641e47epetarj } 2780e5c17a2a2832793a2d4962fa8264025641e47epetarj return 1; 2880e5c17a2a2832793a2d4962fa8264025641e47epetarj} 2980e5c17a2a2832793a2d4962fa8264025641e47epetarj 3080e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic int testcode(int code, int want) 3180e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 3280e5c17a2a2832793a2d4962fa8264025641e47epetarj if (code != want) { 3380e5c17a2a2832793a2d4962fa8264025641e47epetarj fprintf(stderr, " FAIL: expected si_code==%d, not %d\n", want, code); 3480e5c17a2a2832793a2d4962fa8264025641e47epetarj return 0; 3580e5c17a2a2832793a2d4962fa8264025641e47epetarj } 3680e5c17a2a2832793a2d4962fa8264025641e47epetarj return 1; 3780e5c17a2a2832793a2d4962fa8264025641e47epetarj} 3880e5c17a2a2832793a2d4962fa8264025641e47epetarj 3980e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic void handler(int sig, siginfo_t *si, void *uc) 4080e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 4180e5c17a2a2832793a2d4962fa8264025641e47epetarj int ok = 1; 4280e5c17a2a2832793a2d4962fa8264025641e47epetarj 4380e5c17a2a2832793a2d4962fa8264025641e47epetarj ok = ok && testsig(sig, curr_test->sig); 4480e5c17a2a2832793a2d4962fa8264025641e47epetarj ok = ok && testcode(si->si_code, curr_test->code); 4580e5c17a2a2832793a2d4962fa8264025641e47epetarj 4680e5c17a2a2832793a2d4962fa8264025641e47epetarj if (ok) 4780e5c17a2a2832793a2d4962fa8264025641e47epetarj fprintf(stderr, " PASS\n"); 4880e5c17a2a2832793a2d4962fa8264025641e47epetarj 4980e5c17a2a2832793a2d4962fa8264025641e47epetarj siglongjmp(escape, ok + 1); 5080e5c17a2a2832793a2d4962fa8264025641e47epetarj} 5180e5c17a2a2832793a2d4962fa8264025641e47epetarj 5280e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic void test1(void) 5380e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 5480e5c17a2a2832793a2d4962fa8264025641e47epetarj __asm__ volatile("li $t0, 0x80000000\n\t" 5580e5c17a2a2832793a2d4962fa8264025641e47epetarj "move $t1, $t0\n\t" 5680e5c17a2a2832793a2d4962fa8264025641e47epetarj "add $a0, $t0, $t1\n\t" 5780e5c17a2a2832793a2d4962fa8264025641e47epetarj : : : "t0", "t1", "a0", "cc", "memory"); 5880e5c17a2a2832793a2d4962fa8264025641e47epetarj} 5980e5c17a2a2832793a2d4962fa8264025641e47epetarj 6080e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic void test2() 6180e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 6280e5c17a2a2832793a2d4962fa8264025641e47epetarj __asm__ volatile("li $t0, 0x7fffffff\n\t" 6380e5c17a2a2832793a2d4962fa8264025641e47epetarj "addi $a0, $t0, 0x7fff\n\t" 6480e5c17a2a2832793a2d4962fa8264025641e47epetarj : : : "t0", "a0", "cc", "memory"); 6580e5c17a2a2832793a2d4962fa8264025641e47epetarj} 6680e5c17a2a2832793a2d4962fa8264025641e47epetarj 6780e5c17a2a2832793a2d4962fa8264025641e47epetarjstatic void test3(void) 6880e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 6980e5c17a2a2832793a2d4962fa8264025641e47epetarj __asm__ volatile("li $t0, 0xffff0000\n\t" 7080e5c17a2a2832793a2d4962fa8264025641e47epetarj "li $t1, 0x7fffffff\n\t" 7180e5c17a2a2832793a2d4962fa8264025641e47epetarj "sub $a0, $t0, $t1\n\t" 7280e5c17a2a2832793a2d4962fa8264025641e47epetarj : : : "t0", "t1", "a0", "cc", "memory"); 7380e5c17a2a2832793a2d4962fa8264025641e47epetarj} 7480e5c17a2a2832793a2d4962fa8264025641e47epetarj 7580e5c17a2a2832793a2d4962fa8264025641e47epetarjint main() 7680e5c17a2a2832793a2d4962fa8264025641e47epetarj{ 7780e5c17a2a2832793a2d4962fa8264025641e47epetarj int i; 7880e5c17a2a2832793a2d4962fa8264025641e47epetarj static const int sigs[] = { SIGFPE }; 7980e5c17a2a2832793a2d4962fa8264025641e47epetarj struct sigaction sa; 8080e5c17a2a2832793a2d4962fa8264025641e47epetarj sa.sa_sigaction = handler; 8180e5c17a2a2832793a2d4962fa8264025641e47epetarj sa.sa_flags = SA_SIGINFO; 8280e5c17a2a2832793a2d4962fa8264025641e47epetarj sigfillset(&sa.sa_mask); 8380e5c17a2a2832793a2d4962fa8264025641e47epetarj 8480e5c17a2a2832793a2d4962fa8264025641e47epetarj for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++) 8580e5c17a2a2832793a2d4962fa8264025641e47epetarj sigaction(sigs[i], &sa, NULL); 8680e5c17a2a2832793a2d4962fa8264025641e47epetarj 8780e5c17a2a2832793a2d4962fa8264025641e47epetarj const struct test tests[] = { 8880e5c17a2a2832793a2d4962fa8264025641e47epetarj#define T(n, sig, code) { test##n, sig, code } 8980e5c17a2a2832793a2d4962fa8264025641e47epetarj T(1, SIGFPE, FPE_INTOVF), 9080e5c17a2a2832793a2d4962fa8264025641e47epetarj T(2, SIGFPE, FPE_INTOVF), 9180e5c17a2a2832793a2d4962fa8264025641e47epetarj T(3, SIGFPE, FPE_INTOVF), 9280e5c17a2a2832793a2d4962fa8264025641e47epetarj#undef T 9380e5c17a2a2832793a2d4962fa8264025641e47epetarj }; 9480e5c17a2a2832793a2d4962fa8264025641e47epetarj 9580e5c17a2a2832793a2d4962fa8264025641e47epetarj for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) { 9680e5c17a2a2832793a2d4962fa8264025641e47epetarj curr_test = &tests[i]; 9780e5c17a2a2832793a2d4962fa8264025641e47epetarj if (sigsetjmp(escape, 1) == 0) { 9880e5c17a2a2832793a2d4962fa8264025641e47epetarj fprintf(stderr, "Test %d: ", i+1); 9980e5c17a2a2832793a2d4962fa8264025641e47epetarj tests[i].test(); 10080e5c17a2a2832793a2d4962fa8264025641e47epetarj fprintf(stderr, " FAIL: no fault, or handler returned\n"); 10180e5c17a2a2832793a2d4962fa8264025641e47epetarj } 10280e5c17a2a2832793a2d4962fa8264025641e47epetarj } 10380e5c17a2a2832793a2d4962fa8264025641e47epetarj return 0; 10480e5c17a2a2832793a2d4962fa8264025641e47epetarj} 105