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 "tests/sys_mman.h" 10#include <unistd.h> 11 12struct test { 13 void (*test)(void); 14 int sig; 15 int code; 16 volatile void *addr; 17}; 18 19static const struct test *cur_test; 20 21static jmp_buf escape; 22 23#define BADADDR ((int *)0x1234) 24 25#define FILESIZE (16*1024) 26#define MAPSIZE (2*FILESIZE) 27 28static char volatile *volatile mapping; 29 30static int testsig(int sig, int want) 31{ 32 if (sig != want) { 33 fprintf(stderr, " FAIL: expected signal %d, not %d\n", want, sig); 34 return 0; 35 } 36 return 1; 37} 38 39static int testcode(int code, int want) 40{ 41 if (code != want) { 42 fprintf(stderr, " FAIL: expected si_code==%d, not %d\n", want, code); 43 return 0; 44 } 45 return 1; 46} 47 48static int testaddr(void *addr, volatile void *want) 49{ 50 if (addr != want) { 51 fprintf(stderr, " FAIL: expected si_addr==%p, not %p\n", want, addr); 52 return 0; 53 } 54 return 1; 55 56} 57 58static void handler(int sig, siginfo_t *si, void *uc) 59{ 60 int ok = 1; 61 62 ok = ok && testsig(sig, cur_test->sig); 63 ok = ok && testcode(si->si_code, cur_test->code); 64 if (cur_test->addr) 65 ok = ok && testaddr(si->si_addr, cur_test->addr); 66 67 if (ok) 68 fprintf(stderr, " PASS\n"); 69 70 siglongjmp(escape, ok + 1); 71} 72 73 74extern char test1_ill; 75static void test1() 76{ 77 asm volatile("test1_ill: ud2"); 78} 79 80static void test2() 81{ 82 asm volatile ("int3"); 83} 84 85static void test3() 86{ 87 asm volatile ("int $0x10"); 88} 89 90int main() 91{ 92 int fd, i; 93 static const int sigs[] = { SIGSEGV, SIGILL, SIGBUS, SIGFPE, SIGTRAP }; 94 struct sigaction sa; 95 96 sa.sa_sigaction = handler; 97 sa.sa_flags = SA_SIGINFO; 98 sigfillset(&sa.sa_mask); 99 100 for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++) 101 sigaction(sigs[i], &sa, NULL); 102 103 fd = open("faultstatus.tmp", O_CREAT|O_TRUNC|O_EXCL, 0600); 104 if (fd == -1) { 105 perror("tmpfile"); 106 exit(1); 107 } 108 unlink("faultstatus.tmp"); 109 ftruncate(fd, FILESIZE); 110 111 mapping = mmap(0, MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0); 112 close(fd); 113 114 { 115 const struct test tests[] = { 116#define T(n, sig, code, addr) { test##n, sig, code, addr } 117 T(1, SIGILL, ILL_ILLOPN, &test1_ill), 118 119 T(2, SIGTRAP, 128, 0), /* TRAP_BRKPT? */ 120 T(3, SIGSEGV, 128, 0), 121#undef T 122 }; 123 124 for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) { 125 cur_test = &tests[i]; 126 127 if (sigsetjmp(escape, 1) == 0) { 128 fprintf(stderr, "Test %d: ", i+1); 129 tests[i].test(); 130 fprintf(stderr, " FAIL: no fault, or handler returned\n"); 131 } 132 } 133 } 134 135 return 0; 136} 137 138