diff options
Diffstat (limited to 'tests/testsig.c')
-rw-r--r-- | tests/testsig.c | 118 |
1 files changed, 93 insertions, 25 deletions
diff --git a/tests/testsig.c b/tests/testsig.c index 27ea78c6a9..5f6d3705e5 100644 --- a/tests/testsig.c +++ b/tests/testsig.c @@ -26,13 +26,15 @@ void alarm_handler(int sig) #define REG_ESP ESP #define REG_EIP EIP #define REG_EFL EFL +#define REG_TRAPNO TRAPNO +#define REG_ERR ERR #endif void dump_regs(struct ucontext *uc) { printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" - "EFL=%08x EIP=%08x\n", + "EFL=%08x EIP=%08x trapno=%02x err=%08x\n", uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX], uc->uc_mcontext.gregs[REG_ECX], @@ -42,7 +44,9 @@ void dump_regs(struct ucontext *uc) uc->uc_mcontext.gregs[REG_EBP], uc->uc_mcontext.gregs[REG_ESP], uc->uc_mcontext.gregs[REG_EFL], - uc->uc_mcontext.gregs[REG_EIP]); + uc->uc_mcontext.gregs[REG_EIP], + uc->uc_mcontext.gregs[REG_TRAPNO], + uc->uc_mcontext.gregs[REG_ERR]); } void sig_handler(int sig, siginfo_t *info, void *puc) @@ -58,19 +62,22 @@ void sig_handler(int sig, siginfo_t *info, void *puc) } int v1; +int tab[2]; int main(int argc, char **argv) { struct sigaction act; - int i; + int val; + act.sa_sigaction = sig_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &act, NULL); + sigaction(SIGILL, &act, NULL); + sigaction(SIGSEGV, &act, NULL); + /* test division by zero reporting */ if (setjmp(jmp_env) == 0) { - act.sa_sigaction = sig_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_ONESHOT; - sigaction(SIGFPE, &act, NULL); - /* now divide by zero */ v1 = 0; v1 = 2 / v1; @@ -78,33 +85,94 @@ int main(int argc, char **argv) /* test illegal instruction reporting */ if (setjmp(jmp_env) == 0) { - act.sa_sigaction = sig_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_ONESHOT; - sigaction(SIGILL, &act, NULL); - /* now execute an invalid instruction */ asm volatile("ud2"); } /* test SEGV reporting */ if (setjmp(jmp_env) == 0) { - act.sa_sigaction = sig_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_ONESHOT; - sigaction(SIGSEGV, &act, NULL); - /* now store in an invalid address */ *(char *)0x1234 = 1; } + + /* test SEGV reporting */ + if (setjmp(jmp_env) == 0) { + /* read from an invalid address */ + v1 = *(char *)0x1234; + } - act.sa_handler = alarm_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - sigaction(SIGALRM, &act, NULL); - alarm(1); - for(i = 0;i < 2; i++) { - sleep(1); + printf("segment GPF exception:\n"); + if (setjmp(jmp_env) == 0) { + /* load an invalid segment */ + asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); + } + + printf("INT exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("int $0xfd"); + } + + printf("CLI exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("cli"); + } + + printf("STI exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("cli"); + } + + printf("INTO exception:\n"); + if (setjmp(jmp_env) == 0) { + /* overflow exception */ + asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); + } + + printf("BOUND exception:\n"); + if (setjmp(jmp_env) == 0) { + /* bound exception */ + tab[0] = 1; + tab[1] = 10; + asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); + } + + printf("OUTB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); + } + + printf("INB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); } + + printf("REP OUTSB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); + } + + printf("REP INSB exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); + } + + printf("HLT exception:\n"); + if (setjmp(jmp_env) == 0) { + asm volatile ("hlt" : : "d" (0x4321), "D" (tab), "c" (1)); + } + +#if 0 + { + int i; + act.sa_handler = alarm_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + alarm(1); + for(i = 0;i < 2; i++) { + sleep(1); + } + } +#endif return 0; } |