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
11struct test {
12   void (*test)(void);
13   int sig;
14   int code;
15};
16
17static const struct test *curr_test;
18
19static jmp_buf escape;
20
21static 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
30static 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
39static 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
52static 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
60static 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
67static 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
75int 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