mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-08 02:06:42 +00:00
more exception tests - support for precise exceptions
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@188 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
a37904dd86
commit
e3b32540df
@ -1063,8 +1063,6 @@ void test_vm86(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
jmp_buf jmp_env;
|
jmp_buf jmp_env;
|
||||||
int dump_eip;
|
|
||||||
int dump_si_addr;
|
|
||||||
int v1;
|
int v1;
|
||||||
int tab[2];
|
int tab[2];
|
||||||
|
|
||||||
@ -1074,23 +1072,21 @@ void sig_handler(int sig, siginfo_t *info, void *puc)
|
|||||||
|
|
||||||
printf("si_signo=%d si_errno=%d si_code=%d",
|
printf("si_signo=%d si_errno=%d si_code=%d",
|
||||||
info->si_signo, info->si_errno, info->si_code);
|
info->si_signo, info->si_errno, info->si_code);
|
||||||
if (dump_si_addr) {
|
printf(" si_addr=0x%08lx",
|
||||||
printf(" si_addr=0x%08lx",
|
(unsigned long)info->si_addr);
|
||||||
(unsigned long)info->si_addr);
|
|
||||||
}
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("trapno=0x%02x err=0x%08x",
|
printf("trapno=0x%02x err=0x%08x",
|
||||||
uc->uc_mcontext.gregs[REG_TRAPNO],
|
uc->uc_mcontext.gregs[REG_TRAPNO],
|
||||||
uc->uc_mcontext.gregs[REG_ERR]);
|
uc->uc_mcontext.gregs[REG_ERR]);
|
||||||
if (dump_eip)
|
printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]);
|
||||||
printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]);
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
longjmp(jmp_env, 1);
|
longjmp(jmp_env, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_exceptions(void)
|
void test_exceptions(void)
|
||||||
{
|
{
|
||||||
|
struct modify_ldt_ldt_s ldt;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
volatile int val;
|
volatile int val;
|
||||||
|
|
||||||
@ -1100,20 +1096,18 @@ void test_exceptions(void)
|
|||||||
sigaction(SIGFPE, &act, NULL);
|
sigaction(SIGFPE, &act, NULL);
|
||||||
sigaction(SIGILL, &act, NULL);
|
sigaction(SIGILL, &act, NULL);
|
||||||
sigaction(SIGSEGV, &act, NULL);
|
sigaction(SIGSEGV, &act, NULL);
|
||||||
|
sigaction(SIGBUS, &act, NULL);
|
||||||
sigaction(SIGTRAP, &act, NULL);
|
sigaction(SIGTRAP, &act, NULL);
|
||||||
|
|
||||||
/* test division by zero reporting */
|
/* test division by zero reporting */
|
||||||
dump_eip = 0;
|
printf("DIVZ exception:\n");
|
||||||
dump_si_addr = 0;
|
|
||||||
printf("DIVZ exception (currently imprecise):\n");
|
|
||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
/* now divide by zero */
|
/* now divide by zero */
|
||||||
v1 = 0;
|
v1 = 0;
|
||||||
v1 = 2 / v1;
|
v1 = 2 / v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_si_addr = 1;
|
printf("BOUND exception:\n");
|
||||||
printf("BOUND exception (currently imprecise):\n");
|
|
||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
/* bound exception */
|
/* bound exception */
|
||||||
tab[0] = 1;
|
tab[0] = 1;
|
||||||
@ -1121,27 +1115,50 @@ void test_exceptions(void)
|
|||||||
asm volatile ("bound %0, %1" : : "r" (11), "m" (tab));
|
asm volatile ("bound %0, %1" : : "r" (11), "m" (tab));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test SEGV reporting */
|
printf("segment exceptions:\n");
|
||||||
printf("PF exception (currently imprecise):\n");
|
|
||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
/* load an invalid segment */
|
||||||
|
asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));
|
||||||
|
}
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
/* null data segment is valid */
|
||||||
|
asm volatile ("movl %0, %%fs" : : "r" (3));
|
||||||
|
/* null stack segment */
|
||||||
|
asm volatile ("movl %0, %%ss" : : "r" (3));
|
||||||
|
}
|
||||||
|
|
||||||
|
ldt.entry_number = 1;
|
||||||
|
ldt.base_addr = (unsigned long)&seg_data1;
|
||||||
|
ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
|
||||||
|
ldt.seg_32bit = 1;
|
||||||
|
ldt.contents = MODIFY_LDT_CONTENTS_DATA;
|
||||||
|
ldt.read_exec_only = 0;
|
||||||
|
ldt.limit_in_pages = 1;
|
||||||
|
ldt.seg_not_present = 1;
|
||||||
|
ldt.useable = 1;
|
||||||
|
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
|
||||||
|
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
/* segment not present */
|
||||||
|
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test SEGV reporting */
|
||||||
|
printf("PF exception:\n");
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
val = 1;
|
||||||
/* now store in an invalid address */
|
/* now store in an invalid address */
|
||||||
*(char *)0x1234 = 1;
|
*(char *)0x1234 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test SEGV reporting */
|
/* test SEGV reporting */
|
||||||
printf("PF exception (currently imprecise):\n");
|
printf("PF exception:\n");
|
||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
val = 1;
|
||||||
/* read from an invalid address */
|
/* read from an invalid address */
|
||||||
v1 = *(char *)0x1234;
|
v1 = *(char *)0x1234;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("segment GPF exception (currently imprecise):\n");
|
|
||||||
if (setjmp(jmp_env) == 0) {
|
|
||||||
/* load an invalid segment */
|
|
||||||
asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_eip = 1;
|
|
||||||
/* test illegal instruction reporting */
|
/* test illegal instruction reporting */
|
||||||
printf("UD2 exception:\n");
|
printf("UD2 exception:\n");
|
||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
@ -1153,6 +1170,18 @@ void test_exceptions(void)
|
|||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
asm volatile ("int $0xfd");
|
asm volatile ("int $0xfd");
|
||||||
}
|
}
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
asm volatile ("int $0x01");
|
||||||
|
}
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
asm volatile (".byte 0xcd, 0x03");
|
||||||
|
}
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
asm volatile ("int $0x04");
|
||||||
|
}
|
||||||
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
asm volatile ("int $0x05");
|
||||||
|
}
|
||||||
|
|
||||||
printf("INT3 exception:\n");
|
printf("INT3 exception:\n");
|
||||||
if (setjmp(jmp_env) == 0) {
|
if (setjmp(jmp_env) == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user