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 "li $a0, 0x7fff\n\t"
64 "add $a0, $t0, $a0\n\t"
65 : : : "t0", "a0", "cc", "memory");
66 }
67
test3(void)68 static void test3(void)
69 {
70 __asm__ volatile("li $t0, 0xffff0000\n\t"
71 "li $t1, 0x7fffffff\n\t"
72 "sub $a0, $t0, $t1\n\t"
73 : : : "t0", "t1", "a0", "cc", "memory");
74 }
75
main()76 int main()
77 {
78 int i;
79 static const int sigs[] = { SIGFPE };
80 struct sigaction sa;
81 sa.sa_sigaction = handler;
82 sa.sa_flags = SA_SIGINFO;
83 sigfillset(&sa.sa_mask);
84
85 for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++)
86 sigaction(sigs[i], &sa, NULL);
87
88 const struct test tests[] = {
89 #define T(n, sig, code) { test##n, sig, code }
90 T(1, SIGFPE, FPE_INTOVF),
91 T(2, SIGFPE, FPE_INTOVF),
92 T(3, SIGFPE, FPE_INTOVF),
93 #undef T
94 };
95
96 for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
97 curr_test = &tests[i];
98 if (sigsetjmp(escape, 1) == 0) {
99 fprintf(stderr, "Test %d: ", i+1);
100 tests[i].test();
101 fprintf(stderr, " FAIL: no fault, or handler returned\n");
102 }
103 }
104 return 0;
105 }
106