Home | History | Annotate | Download | only in amd64
      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 
     12 struct test {
     13 	void (*test)(void);
     14 	int sig;
     15 	int code;
     16 	volatile void *addr;
     17 };
     18 
     19 static const struct test *cur_test;
     20 
     21 static jmp_buf escape;
     22 
     23 #define BADADDR	((int *)0x1234)
     24 
     25 #define FILESIZE	(16*1024)
     26 #define MAPSIZE		(2*FILESIZE)
     27 
     28 static char volatile *volatile mapping;
     29 
     30 static 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 
     39 static 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 
     48 static 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 
     58 static 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 
     74 extern char test1_ill;
     75 static void test1()
     76 {
     77 	asm volatile("test1_ill: ud2");
     78 }
     79 
     80 static void test2()
     81 {
     82 	asm volatile ("int3");
     83 }
     84 
     85 static void test3()
     86 {
     87 	asm volatile ("int $0x10");
     88 }
     89 
     90 int 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