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
testsig(int sig,int want)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
testcode(int code,int want)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
handler(int sig,siginfo_t * si,void * uc)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
test1(void)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
test2()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
test3(void)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
main()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