]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Split faultstatus into the platform independent tests and those
authorTom Hughes <tom@compton.nu>
Wed, 2 Nov 2005 16:15:55 +0000 (16:15 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 2 Nov 2005 16:15:55 +0000 (16:15 +0000)
which are x86 specific. The first three x86 specific ones should
work on amd64 as well so I have added those as amd64 tests.

Note that the x86/amd64 tests will still fail as VEX doesn't
always trigger the right sort of signal for faulting instructions
at the moment.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4992

none/tests/amd64/Makefile.am
none/tests/amd64/faultstatus.c [new file with mode: 0644]
none/tests/amd64/faultstatus.stderr.exp [new file with mode: 0644]
none/tests/amd64/faultstatus.vgtest [new file with mode: 0644]
none/tests/faultstatus.c
none/tests/faultstatus.stderr.exp
none/tests/x86/Makefile.am
none/tests/x86/faultstatus.c [new file with mode: 0644]
none/tests/x86/faultstatus.stderr.exp [new file with mode: 0644]
none/tests/x86/faultstatus.vgtest [new file with mode: 0644]

index 06d60dea4e62cdfd2afdbb9bce51378f2466b9a2..7d0ab7f16a8828eb7d8b62cc18e306760ce20376 100644 (file)
@@ -5,6 +5,7 @@ CLEANFILES = $(addsuffix .c,$(INSN_TESTS))
 INSN_TESTS=insn_mmx insn_sse insn_sse2 insn_fpu
 
 EXTRA_DIST = $(noinst_SCRIPTS) \
+       faultstatus.vgtest faultstatus.stderr.exp \
        $(addsuffix .stderr.exp,$(INSN_TESTS)) \
        $(addsuffix .stdout.exp,$(INSN_TESTS)) \
        $(addsuffix .vgtest,$(INSN_TESTS)) \
@@ -13,7 +14,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
         smc1.stderr.exp smc1.stdout.exp smc1.vgtest
 
 check_PROGRAMS = \
-       $(INSN_TESTS) looper jrcxz smc1
+       faultstatus $(INSN_TESTS) looper jrcxz smc1
 
 AM_CFLAGS   = $(WERROR) -Winline -Wall -Wshadow -g -I$(top_srcdir)/include
 AM_CXXFLAGS = $(AM_CFLAGS)
diff --git a/none/tests/amd64/faultstatus.c b/none/tests/amd64/faultstatus.c
new file mode 100644 (file)
index 0000000..6337cac
--- /dev/null
@@ -0,0 +1,143 @@
+/* 
+   Check that a fault signal handler gets the expected info
+ */
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+struct test {
+       void (*test)(void);
+       int sig;
+       int code;
+       volatile void *addr;
+};
+
+static const struct test *cur_test;
+
+static int zero();
+
+static jmp_buf escape;
+
+#define BADADDR        ((int *)0x1234)
+
+#define FILESIZE       (16*1024)
+#define MAPSIZE                (2*FILESIZE)
+
+static char volatile *volatile mapping;
+
+static int testsig(int sig, int want)
+{
+       if (sig != want) {
+               fprintf(stderr, "  FAIL: expected signal %d, not %d\n", want, sig);
+               return 0;
+       } 
+       return 1;
+}
+
+static int testcode(int code, int want)
+{
+       if (code != want) {
+               fprintf(stderr, "  FAIL: expected si_code==%d, not %d\n", want, code);
+               return 0;
+       }
+       return 1;
+}
+
+static int testaddr(void *addr, volatile void *want)
+{
+       if (addr != want) {
+               fprintf(stderr, "  FAIL: expected si_addr==%p, not %p\n", want, addr);
+               return 0;
+       }
+       return 1;
+
+}
+
+static void handler(int sig, siginfo_t *si, void *uc)
+{
+       int ok = 1;
+
+       ok = ok && testsig(sig, cur_test->sig);
+       ok = ok && testcode(si->si_code, cur_test->code);
+       if (cur_test->addr)
+               ok = ok && testaddr(si->si_addr, cur_test->addr);
+
+       if (ok)
+               fprintf(stderr, "  PASS\n");
+
+       siglongjmp(escape, ok + 1);
+}
+
+
+extern char test1_ill;
+static void test1()
+{
+       asm volatile("test1_ill: ud2");
+}
+
+static void test2()
+{
+       asm volatile ("int3");
+}
+
+static void test3()
+{
+       asm volatile ("int $0x10");
+}
+
+int main()
+{
+       int fd, i;
+       static const int sigs[] = { SIGSEGV, SIGILL, SIGBUS, SIGFPE, SIGTRAP };
+       struct sigaction sa;
+
+       sa.sa_sigaction = handler;
+       sa.sa_flags = SA_SIGINFO;
+       sigfillset(&sa.sa_mask);
+       
+       for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++)
+               sigaction(sigs[i], &sa, NULL);
+
+       fd = open("faultstatus.tmp", O_CREAT|O_TRUNC|O_EXCL, 0600);
+       if (fd == -1) {
+               perror("tmpfile");
+               exit(1);
+       }
+       unlink("faultstatus.tmp");
+       ftruncate(fd, FILESIZE);
+
+       mapping = mmap(0, MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0);
+       close(fd);
+
+       {
+               const struct test tests[] = {
+#define T(n, sig, code, addr) { test##n, sig, code, addr }
+                       T(1, SIGILL,    ILL_ILLOPN,     &test1_ill),
+
+                       T(2, SIGTRAP,   128,            0), /* TRAP_BRKPT? */
+                       T(3, SIGSEGV,   128,            0),
+#undef T
+               };
+
+               for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
+                       cur_test = &tests[i];
+               
+                       if (sigsetjmp(escape, 1) == 0) {
+                               fprintf(stderr, "Test %d: ", i+1);
+                               tests[i].test();
+                               fprintf(stderr, "  FAIL: no fault, or handler returned\n");
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int zero()
+{
+       return 0;
+}
diff --git a/none/tests/amd64/faultstatus.stderr.exp b/none/tests/amd64/faultstatus.stderr.exp
new file mode 100644 (file)
index 0000000..b91b047
--- /dev/null
@@ -0,0 +1,5 @@
+
+Test 1:   PASS
+Test 2:   PASS
+Test 3:   PASS
+
diff --git a/none/tests/amd64/faultstatus.vgtest b/none/tests/amd64/faultstatus.vgtest
new file mode 100644 (file)
index 0000000..d388f29
--- /dev/null
@@ -0,0 +1 @@
+prog: faultstatus
index 906120aa813ead6c3b65302f62a30a7c37fa7273..97d1f3741c50fa0559f3caf56073b8ef128db3d9 100644 (file)
@@ -95,39 +95,6 @@ static void test4()
        (void)v;
 }
 
-#ifdef __i386__
-extern char test5_ill;
-static void test5()
-{
-       asm volatile("test5_ill: ud2");
-}
-
-static void test6()
-{
-       asm volatile ("int3");
-}
-
-static void test7()
-{
-       asm volatile ("int $0x10");
-}
-
-static void test8()
-{
-       volatile int a;
-       asm volatile ("add $1, %0;"/* set OF */
-                     "into"
-                     : "=a" (a) : "0" (0x7fffffff) : "cc");
-}
-
-static void test9()
-{
-       static int limit[2] = { 0, 10 };
-
-       asm volatile ("bound %0, %1" : : "r" (11), "m" (limit[0]));
-}
-#endif /* __i386__ */
-
 int main()
 {
        int fd, i;
@@ -159,18 +126,6 @@ int main()
                        T(2, SIGSEGV,   SEGV_ACCERR,    mapping),
                        T(3, SIGBUS,    BUS_ADRERR,     &mapping[FILESIZE+10]),
                        T(4, SIGFPE,    FPE_INTDIV,     0),
-#ifdef __i386__
-                       T(5, SIGILL,    ILL_ILLOPN,     &test5_ill),
-
-                       T(6, SIGTRAP,   128,            0), /* TRAP_BRKPT? */
-                       T(7, SIGSEGV,   128,            0),
-                       T(8, SIGSEGV,   128,            0),
-
-                       /* This is an expected failure - Valgrind
-                          doesn't implement the BOUND instruction,
-                          and so issues a SIGILL instead. */
-                       T(9, SIGSEGV,   128,            0),
-#endif /* __i386__ */
 #undef T
                };
 
index b214bde17f8fb5da71f1521849b0d5d5904f5627..af5744bfbebbea1fb953e7e63cbab1dbe9ea3dd6 100644 (file)
@@ -3,11 +3,4 @@ Test 1:   PASS
 Test 2:   PASS
 Test 3:   PASS
 Test 4:   PASS
-Test 5:   PASS
-Test 6:   PASS
-Test 7:   PASS
-Test 8:   PASS
-Test 9: disInstr: unhandled instruction bytes: 0x........ 0x........ 0x........ 0x........
-          at 0x........: test9 (faultstatus.c:127)
-  FAIL: expected signal 11, not 4
 
index a8c9e7ec25e2a0f619632a05b2efddc7760cd847..1af97badbf0ea94f9329f8bc8c66382ffa157636 100644 (file)
@@ -9,6 +9,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        bt_literal.stderr.exp bt_literal.stdout.exp bt_literal.vgtest \
        cpuid.stderr.exp cpuid.stdout.exp cpuid.vgtest \
        cmpxchg8b.stderr.exp cmpxchg8b.stdout.exp cmpxchg8b.vgtest \
+       faultstatus.vgtest faultstatus.stderr.exp \
        fpu_lazy_eflags.stderr.exp fpu_lazy_eflags.stdout.exp \
        fpu_lazy_eflags.vgtest \
        fxtract.stdout.exp fxtract.stderr.exp fxtract.vgtest \
@@ -28,8 +29,8 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        yield.stderr.exp yield.stdout.exp yield.vgtest
 
 check_PROGRAMS = \
-       badseg bt_everything bt_literal cmpxchg8b cpuid fpu_lazy_eflags \
-       fxtract \
+       badseg bt_everything bt_literal cmpxchg8b cpuid \
+       faultstatus fpu_lazy_eflags fxtract \
        getseg incdec_alt $(INSN_TESTS) \
        lahf looper int pushpopseg sbbmisc \
        seg_override sigcontext smc1 yield
diff --git a/none/tests/x86/faultstatus.c b/none/tests/x86/faultstatus.c
new file mode 100644 (file)
index 0000000..5d39753
--- /dev/null
@@ -0,0 +1,164 @@
+/* 
+   Check that a fault signal handler gets the expected info
+ */
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+struct test {
+       void (*test)(void);
+       int sig;
+       int code;
+       volatile void *addr;
+};
+
+static const struct test *cur_test;
+
+static int zero();
+
+static jmp_buf escape;
+
+#define BADADDR        ((int *)0x1234)
+
+#define FILESIZE       (16*1024)
+#define MAPSIZE                (2*FILESIZE)
+
+static char volatile *volatile mapping;
+
+static int testsig(int sig, int want)
+{
+       if (sig != want) {
+               fprintf(stderr, "  FAIL: expected signal %d, not %d\n", want, sig);
+               return 0;
+       } 
+       return 1;
+}
+
+static int testcode(int code, int want)
+{
+       if (code != want) {
+               fprintf(stderr, "  FAIL: expected si_code==%d, not %d\n", want, code);
+               return 0;
+       }
+       return 1;
+}
+
+static int testaddr(void *addr, volatile void *want)
+{
+       if (addr != want) {
+               fprintf(stderr, "  FAIL: expected si_addr==%p, not %p\n", want, addr);
+               return 0;
+       }
+       return 1;
+
+}
+
+static void handler(int sig, siginfo_t *si, void *uc)
+{
+       int ok = 1;
+
+       ok = ok && testsig(sig, cur_test->sig);
+       ok = ok && testcode(si->si_code, cur_test->code);
+       if (cur_test->addr)
+               ok = ok && testaddr(si->si_addr, cur_test->addr);
+
+       if (ok)
+               fprintf(stderr, "  PASS\n");
+
+       siglongjmp(escape, ok + 1);
+}
+
+
+extern char test1_ill;
+static void test1()
+{
+       asm volatile("test1_ill: ud2");
+}
+
+static void test2()
+{
+       asm volatile ("int3");
+}
+
+static void test3()
+{
+       asm volatile ("int $0x10");
+}
+
+static void test4()
+{
+       volatile int a;
+       asm volatile ("add $1, %0;"/* set OF */
+                     "into"
+                     : "=a" (a) : "0" (0x7fffffff) : "cc");
+}
+
+static void test5()
+{
+       static int limit[2] = { 0, 10 };
+
+       asm volatile ("bound %0, %1" : : "r" (11), "m" (limit[0]));
+}
+
+int main()
+{
+       int fd, i;
+       static const int sigs[] = { SIGSEGV, SIGILL, SIGBUS, SIGFPE, SIGTRAP };
+       struct sigaction sa;
+
+       sa.sa_sigaction = handler;
+       sa.sa_flags = SA_SIGINFO;
+       sigfillset(&sa.sa_mask);
+       
+       for(i = 0; i < sizeof(sigs)/sizeof(*sigs); i++)
+               sigaction(sigs[i], &sa, NULL);
+
+       fd = open("faultstatus.tmp", O_CREAT|O_TRUNC|O_EXCL, 0600);
+       if (fd == -1) {
+               perror("tmpfile");
+               exit(1);
+       }
+       unlink("faultstatus.tmp");
+       ftruncate(fd, FILESIZE);
+
+       mapping = mmap(0, MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0);
+       close(fd);
+
+       {
+               const struct test tests[] = {
+#define T(n, sig, code, addr) { test##n, sig, code, addr }
+                       T(1, SIGILL,    ILL_ILLOPN,     &test1_ill),
+
+                       T(2, SIGTRAP,   128,            0), /* TRAP_BRKPT? */
+                       T(3, SIGSEGV,   128,            0),
+                       T(4, SIGSEGV,   128,            0),
+
+                       /* This is an expected failure - Valgrind
+                          doesn't implement the BOUND instruction,
+                          and so issues a SIGILL instead. */
+                       T(5, SIGSEGV,   128,            0),
+#undef T
+               };
+
+               for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
+                       cur_test = &tests[i];
+               
+                       if (sigsetjmp(escape, 1) == 0) {
+                               fprintf(stderr, "Test %d: ", i+1);
+                               tests[i].test();
+                               fprintf(stderr, "  FAIL: no fault, or handler returned\n");
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int zero()
+{
+       return 0;
+}
diff --git a/none/tests/x86/faultstatus.stderr.exp b/none/tests/x86/faultstatus.stderr.exp
new file mode 100644 (file)
index 0000000..bf574c8
--- /dev/null
@@ -0,0 +1,9 @@
+
+Test 1:   PASS
+Test 2:   PASS
+Test 3:   PASS
+Test 4:   PASS
+Test 5: disInstr: unhandled instruction bytes: 0x........ 0x........ 0x........ 0x........
+          at 0x........: test9 (faultstatus.c:127)
+  FAIL: expected signal 11, not 4
+
diff --git a/none/tests/x86/faultstatus.vgtest b/none/tests/x86/faultstatus.vgtest
new file mode 100644 (file)
index 0000000..d388f29
--- /dev/null
@@ -0,0 +1 @@
+prog: faultstatus