Home | History | Annotate | Download | only in mips32
      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