Bug 385411 s390x: Tests and internals for z13 vector FP support
[valgrind.git] / none / tests / x86 / faultstatus.c
blob6335c19c897fa66310a9e5d7ebc08d393b814f93
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 #include "tests/asm.h"
11 #include "tests/sys_mman.h"
13 struct test {
14 void (*test)(void);
15 int sig;
16 int code;
17 volatile void *addr;
20 static const struct test *cur_test;
24 static jmp_buf escape;
26 #define BADADDR ((int *)0x1234)
28 #define FILESIZE (16*1024)
29 #define MAPSIZE (2*FILESIZE)
31 static char volatile *volatile mapping;
33 static int testsig(int sig, int want)
35 if (sig != want) {
36 fprintf(stderr, " FAIL: expected signal %d, not %d\n", want, sig);
37 return 0;
39 return 1;
42 static int testcode(int code, int want)
44 if (code != want) {
45 fprintf(stderr, " FAIL: expected si_code==%d, not %d\n", want, code);
46 return 0;
48 return 1;
51 static int testaddr(void *addr, volatile void *want)
53 if (addr != want) {
54 fprintf(stderr, " FAIL: expected si_addr==%p, not %p\n", want, addr);
55 return 0;
57 return 1;
61 static void handler(int sig, siginfo_t *si, void *uc)
63 int ok = 1;
65 ok = ok && testsig(sig, cur_test->sig);
66 ok = ok && testcode(si->si_code, cur_test->code);
67 if (cur_test->addr)
68 ok = ok && testaddr(si->si_addr, cur_test->addr);
70 if (ok)
71 fprintf(stderr, " PASS\n");
73 siglongjmp(escape, ok + 1);
77 extern char test1_ill;
78 static void test1()
80 asm volatile(VG_SYM(test1_ill) ": ud2");
83 static void test2()
85 asm volatile ("int3");
88 static void test3()
90 asm volatile ("int $0x10");
93 static void test4()
95 volatile int a;
96 asm volatile ("add $1, %0;"/* set OF */
97 "into"
98 : "=a" (a) : "0" (0x7fffffff) : "cc");
101 static void test5()
103 static int limit[2] = { 0, 10 };
105 asm volatile ("bound %0, %1" : : "r" (11), "m" (limit[0]));
108 int main()
110 int fd, i;
111 static const int sigs[] = { SIGSEGV, SIGILL, SIGBUS, SIGFPE, SIGTRAP };
112 struct sigaction sa;
114 sa.sa_sigaction = handler;
115 sa.sa_flags = SA_SIGINFO;
116 sigfillset(&sa.sa_mask);
118 for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++)
119 sigaction(sigs[i], &sa, NULL);
121 fd = open("faultstatus.tmp", O_CREAT|O_TRUNC|O_EXCL, 0600);
122 if (fd == -1) {
123 perror("tmpfile");
124 exit(1);
126 unlink("faultstatus.tmp");
127 ftruncate(fd, FILESIZE);
129 mapping = mmap(0, MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0);
130 close(fd);
133 const struct test tests[] = {
134 #define T(n, sig, code, addr) { test##n, sig, code, addr }
135 T(1, SIGILL, ILL_ILLOPN, &test1_ill),
137 T(2, SIGTRAP, 128, 0), /* TRAP_BRKPT? */
138 T(3, SIGSEGV, 128, 0),
139 T(4, SIGSEGV, 128, 0),
141 /* This is an expected failure - Valgrind
142 doesn't implement the BOUND instruction,
143 and so issues a SIGILL instead. */
144 T(5, SIGSEGV, 128, 0),
145 #undef T
148 for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
149 cur_test = &tests[i];
151 if (sigsetjmp(escape, 1) == 0) {
152 fprintf(stderr, "Test %d: ", i+1);
153 tests[i].test();
154 fprintf(stderr, " FAIL: no fault, or handler returned\n");
159 return 0;