|
From: Jeremy F. <je...@go...> - 2005-02-04 22:44:18
|
CVS commit by fitzhardinge:
Extend faultstatus to test for all the interrupt-raising instructions.
Valgrind doesn't implement all of these (into and bound), so we get
some expected failures (SIGILL rather than SIGSEGV).
Removes a lot of mostly-duplicate code.
Also, fix a minor conformance bug in SIGILL - the si_addr field is
supposed to point to the illegal instruction.
M +5 -0 coregrind/x86/signal.c 1.13
M +74 -110 none/tests/faultstatus.c 1.3
M +13 -7 none/tests/faultstatus.stderr.exp 1.5
--- valgrind/none/tests/faultstatus.c #1.2:1.3
@@ -10,4 +10,13 @@
#include <unistd.h>
+struct test {
+ void (*test)(void);
+ int sig;
+ int code;
+ volatile void *addr;
+};
+
+static const struct test *cur_test;
+
static int zero();
@@ -49,39 +58,28 @@ static int testaddr(void *addr, volatile
}
-static void test1(void)
-{
- *BADADDR = 'x';
-}
-
-static void handler1(int sig, siginfo_t *si, void *uc)
+static void handler(int sig, siginfo_t *si, void *uc)
{
int ok = 1;
- ok = ok && testsig(sig, SIGSEGV);
- ok = ok && testcode(si->si_code, SEGV_MAPERR);
- ok = ok && testaddr(si->si_addr, BADADDR);
+ 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 1\n");
+ fprintf(stderr, " PASS\n");
- siglongjmp(escape, 1);
+ siglongjmp(escape, ok + 1);
}
-static void test2()
+
+static void test1(void)
{
- mapping[0] = 'x';
+ *BADADDR = 'x';
}
-static void handler2(int sig, siginfo_t *si, void *uc)
+static void test2()
{
- int ok = 1;
-
- ok = ok && testsig(sig, SIGSEGV);
- ok = ok && testcode(si->si_code, SEGV_ACCERR);
- ok = ok && testaddr(si->si_addr, mapping);
- if (ok)
- fprintf(stderr, " PASS 2\n");
-
- siglongjmp(escape, 1);
+ mapping[0] = 'x';
}
@@ -91,49 +89,16 @@ static void test3()
}
-static void handler3(int sig, siginfo_t *si, void *uc)
-{
- int ok = 1;
-
- ok = ok && testsig(sig, SIGBUS);
- ok = ok && testcode(si->si_code, BUS_ADRERR);
- ok = ok && testaddr(si->si_addr, &mapping[FILESIZE+10]);
- if (ok)
- fprintf(stderr, " PASS 3\n");
-
- siglongjmp(escape, 1);
-}
-
static void test4()
{
- asm volatile("ud2");
-}
-
-static void handler4(int sig, siginfo_t *si, void *uc)
-{
- int ok = 1;
-
- ok = ok && testsig(sig, SIGILL);
- ok = ok && testcode(si->si_code, ILL_ILLOPN);
- if (ok)
- fprintf(stderr, " PASS 4\n");
+ volatile int v = 44/zero();
- siglongjmp(escape, 1);
+ (void)v;
}
+#ifdef __i386__
+extern char test5_ill;
static void test5()
{
- volatile int v = 44/zero();
-}
-
-static void handler5(int sig, siginfo_t *si, void *uc)
-{
- int ok = 1;
-
- ok = ok && testsig(sig, SIGFPE);
- ok = ok && testcode(si->si_code, FPE_INTDIV);
- if (ok)
- fprintf(stderr, " PASS 5\n");
-
- siglongjmp(escape, 1);
+ asm volatile("test5_ill: ud2");
}
@@ -143,53 +108,37 @@ static void test6()
}
-static void handler6(int sig, siginfo_t *si, void *uc)
+static void test7()
{
- int ok = 1;
-
- ok = ok && testsig(sig, SIGTRAP);
- ok = ok && testcode(si->si_code, 128); /* should be TRAP_BRKPT */
- if (ok)
- fprintf(stderr, " PASS 6\n");
-
- siglongjmp(escape, 1);
+ asm volatile ("int $0x10");
}
-static void test7()
+static void test8()
{
- asm volatile ("int $0x40");
+ volatile int a;
+ asm volatile ("add $1, %0;"/* set OF */
+ "into"
+ : "=a" (a) : "0" (0x7fffffff) : "cc");
}
-static void handler7(int sig, siginfo_t *si, void *uc)
+static void test9()
{
- int ok = 1;
-
- ok = ok && testsig(sig, SIGSEGV);
- ok = ok && testcode(si->si_code, 128); /* GPF */
- if (ok)
- fprintf(stderr, " PASS 7\n");
+ static int limit[2] = { 0, 10 };
- siglongjmp(escape, 1);
+ asm volatile ("bound %0, %1" : : "r" (11), "m" (limit));
}
-
+#endif /* __i386__ */
int main()
{
- int fd;
- static const struct test {
- void (*test)(void);
- void (*handler)(int, siginfo_t *, void *);
- } tests[] = {
-#define T(n) { test##n, handler##n }
- T(1),
- T(2),
- T(3),
- T(4),
- T(5),
- T(6),
- T(7),
-#undef T
- };
+ int fd, i;
static const int sigs[] = { SIGSEGV, SIGILL, SIGBUS, SIGFPE, SIGTRAP };
- int i;
+ 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);
@@ -204,13 +153,27 @@ int main()
close(fd);
- for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
- int j;
- struct sigaction sa;
- sa.sa_sigaction = tests[i].handler;
- sa.sa_flags = SA_SIGINFO;
- sigfillset(&sa.sa_mask);
+ {
+ const struct test tests[] = {
+#define T(n, sig, code, addr) { test##n, sig, code, addr }
+ T(1, SIGSEGV, SEGV_MAPERR, BADADDR),
+ 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),
- for(j = 0; j < sizeof(sigs)/sizeof(*sigs); j++)
- sigaction(sigs[j], &sa, NULL);
+ /* These 2 are an expected failure - Valgrind
+ doesn't implement their instructions, and
+ so issues a SIGILL instead. */
+ T(8, SIGSEGV, 128, 0),
+ T(9, SIGSEGV, 128, 0),
+#endif /* __i386__ */
+#undef T
+ };
+
+ for(i = 0; i < sizeof(tests)/sizeof(*tests); i++) {
+ cur_test = &tests[i];
if (sigsetjmp(escape, 1) == 0) {
@@ -220,4 +183,5 @@ int main()
}
}
+ }
return 0;
--- valgrind/none/tests/faultstatus.stderr.exp #1.4:1.5
@@ -1,9 +1,15 @@
-Test 1: PASS 1
-Test 2: PASS 2
-Test 3: PASS 3
-Test 4: PASS 4
-Test 5: PASS 5
-Test 6: PASS 6
-Test 7: PASS 7
+Test 1: PASS
+Test 2: PASS
+Test 3: PASS
+Test 4: PASS
+Test 5: PASS
+Test 6: PASS
+Test 7: PASS
+Test 8: disInstr: unhandled instruction bytes: 0x........ 0x........ 0x........ 0x........
+ at 0x........: test8 (faultstatus.c:118)
+ FAIL: expected signal 11, not 4
+Test 9: disInstr: unhandled instruction bytes: 0x........ 0x........ 0x........ 0x........
+ at 0x........: test9 (faultstatus.c:127)
+ FAIL: expected signal 11, not 4
--- valgrind/coregrind/x86/signal.c #1.12:1.13
@@ -499,4 +499,9 @@ static Addr build_rt_sigframe(ThreadStat
frame->puContext = (Addr)&frame->uContext;
VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
+
+ /* SIGILL defines addr to be the faulting address */
+ if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
+ frame->sigInfo._sifields._sigfault._addr = tst->arch.m_eip;
+
synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
|