1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* 2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Check that a fault signal handler gets the expected info 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <signal.h> 5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdio.h> 6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdlib.h> 7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <fcntl.h> 8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <setjmp.h> 9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <unistd.h> 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstruct test { 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*test)(void); 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int sig; 14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int code; 15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}; 16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const struct test *curr_test; 18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic jmp_buf escape; 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic int testsig(int sig, int want) 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sig != want) { 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fprintf(stderr, " FAIL: expected signal %d, not %d\n", want, sig); 25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; 26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 1; 28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic int testcode(int code, int want) 31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (code != want) { 33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fprintf(stderr, " FAIL: expected si_code==%d, not %d\n", want, code); 34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; 35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 1; 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void handler(int sig, siginfo_t *si, void *uc) 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int ok = 1; 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ok = ok && testsig(sig, curr_test->sig); 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ok = ok && testcode(si->si_code, curr_test->code); 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ok) 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fprintf(stderr, " PASS\n"); 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov siglongjmp(escape, ok + 1); 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void test1(void) 53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile("li $t0, 0x80000000\n\t" 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "move $t1, $t0\n\t" 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "add $a0, $t0, $t1\n\t" 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : : : "t0", "t1", "a0", "cc", "memory"); 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void test2() 61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile("li $t0, 0x7fffffff\n\t" 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "addi $a0, $t0, 0x7fff\n\t" 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : : : "t0", "a0", "cc", "memory"); 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void test3(void) 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ volatile("li $t0, 0xffff0000\n\t" 70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "li $t1, 0x7fffffff\n\t" 71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "sub $a0, $t0, $t1\n\t" 72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : : : "t0", "t1", "a0", "cc", "memory"); 73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint main() 76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int i; 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static const int sigs[] = { SIGFPE }; 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct sigaction sa; 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sa.sa_sigaction = handler; 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sa.sa_flags = SA_SIGINFO; 82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sigfillset(&sa.sa_mask); 83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++) 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sigaction(sigs[i], &sa, NULL); 86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const struct test tests[] = { 88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define T(n, sig, code) { test##n, sig, code } 89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov T(1, SIGFPE, FPE_INTOVF), 90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov T(2, SIGFPE, FPE_INTOVF), 91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov T(3, SIGFPE, FPE_INTOVF), 92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#undef T 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov }; 94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) { 96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov curr_test = &tests[i]; 97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sigsetjmp(escape, 1) == 0) { 98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fprintf(stderr, "Test %d: ", i+1); 99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tests[i].test(); 100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fprintf(stderr, " FAIL: no fault, or handler returned\n"); 101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; 104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 105