1 /* 2 Check that a fault signal handler gets the expected info 3 */ 4 #include <signal.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <fcntl.h> 8 #include <setjmp.h> 9 #include <unistd.h> 10 11 struct test { 12 void (*test)(void); 13 int sig; 14 int code; 15 }; 16 17 static const struct test *curr_test; 18 19 static jmp_buf escape; 20 21 static int testsig(int sig, int want) 22 { 23 if (sig != want) { 24 fprintf(stderr, " FAIL: expected signal %d, not %d\n", want, sig); 25 return 0; 26 } 27 return 1; 28 } 29 30 static int testcode(int code, int want) 31 { 32 if (code != want) { 33 fprintf(stderr, " FAIL: expected si_code==%d, not %d\n", want, code); 34 return 0; 35 } 36 return 1; 37 } 38 39 static void handler(int sig, siginfo_t *si, void *uc) 40 { 41 int ok = 1; 42 43 ok = ok && testsig(sig, curr_test->sig); 44 ok = ok && testcode(si->si_code, curr_test->code); 45 46 if (ok) 47 fprintf(stderr, " PASS\n"); 48 49 siglongjmp(escape, ok + 1); 50 } 51 52 static void test1(void) 53 { 54 __asm__ volatile("li $t0, 0x80000000\n\t" 55 "move $t1, $t0\n\t" 56 "add $a0, $t0, $t1\n\t" 57 : : : "t0", "t1", "a0", "cc", "memory"); 58 } 59 60 static void test2() 61 { 62 __asm__ volatile("li $t0, 0x7fffffff\n\t" 63 "addi $a0, $t0, 0x7fff\n\t" 64 : : : "t0", "a0", "cc", "memory"); 65 } 66 67 static void test3(void) 68 { 69 __asm__ volatile("li $t0, 0xffff0000\n\t" 70 "li $t1, 0x7fffffff\n\t" 71 "sub $a0, $t0, $t1\n\t" 72 : : : "t0", "t1", "a0", "cc", "memory"); 73 } 74 75 int main() 76 { 77 int i; 78 static const int sigs[] = { SIGFPE }; 79 struct sigaction sa; 80 sa.sa_sigaction = handler; 81 sa.sa_flags = SA_SIGINFO; 82 sigfillset(&sa.sa_mask); 83 84 for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++) 85 sigaction(sigs[i], &sa, NULL); 86 87 const struct test tests[] = { 88 #define T(n, sig, code) { test##n, sig, code } 89 T(1, SIGFPE, FPE_INTOVF), 90 T(2, SIGFPE, FPE_INTOVF), 91 T(3, SIGFPE, FPE_INTOVF), 92 #undef T 93 }; 94 95 for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) { 96 curr_test = &tests[i]; 97 if (sigsetjmp(escape, 1) == 0) { 98 fprintf(stderr, "Test %d: ", i+1); 99 tests[i].test(); 100 fprintf(stderr, " FAIL: no fault, or handler returned\n"); 101 } 102 } 103 return 0; 104 } 105