Commit e3b32540dfca281e3981f1a429cac203bcb89287
1 parent
a37904dd
more exception tests - support for precise exceptions
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@188 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
51 additions
and
22 deletions
tests/test-i386.c
@@ -1063,8 +1063,6 @@ void test_vm86(void) | @@ -1063,8 +1063,6 @@ void test_vm86(void) | ||
1063 | #endif | 1063 | #endif |
1064 | 1064 | ||
1065 | jmp_buf jmp_env; | 1065 | jmp_buf jmp_env; |
1066 | -int dump_eip; | ||
1067 | -int dump_si_addr; | ||
1068 | int v1; | 1066 | int v1; |
1069 | int tab[2]; | 1067 | int tab[2]; |
1070 | 1068 | ||
@@ -1074,23 +1072,21 @@ void sig_handler(int sig, siginfo_t *info, void *puc) | @@ -1074,23 +1072,21 @@ void sig_handler(int sig, siginfo_t *info, void *puc) | ||
1074 | 1072 | ||
1075 | printf("si_signo=%d si_errno=%d si_code=%d", | 1073 | printf("si_signo=%d si_errno=%d si_code=%d", |
1076 | info->si_signo, info->si_errno, info->si_code); | 1074 | info->si_signo, info->si_errno, info->si_code); |
1077 | - if (dump_si_addr) { | ||
1078 | - printf(" si_addr=0x%08lx", | ||
1079 | - (unsigned long)info->si_addr); | ||
1080 | - } | 1075 | + printf(" si_addr=0x%08lx", |
1076 | + (unsigned long)info->si_addr); | ||
1081 | printf("\n"); | 1077 | printf("\n"); |
1082 | 1078 | ||
1083 | printf("trapno=0x%02x err=0x%08x", | 1079 | printf("trapno=0x%02x err=0x%08x", |
1084 | uc->uc_mcontext.gregs[REG_TRAPNO], | 1080 | uc->uc_mcontext.gregs[REG_TRAPNO], |
1085 | uc->uc_mcontext.gregs[REG_ERR]); | 1081 | uc->uc_mcontext.gregs[REG_ERR]); |
1086 | - if (dump_eip) | ||
1087 | - printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); | 1082 | + printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); |
1088 | printf("\n"); | 1083 | printf("\n"); |
1089 | longjmp(jmp_env, 1); | 1084 | longjmp(jmp_env, 1); |
1090 | } | 1085 | } |
1091 | 1086 | ||
1092 | void test_exceptions(void) | 1087 | void test_exceptions(void) |
1093 | { | 1088 | { |
1089 | + struct modify_ldt_ldt_s ldt; | ||
1094 | struct sigaction act; | 1090 | struct sigaction act; |
1095 | volatile int val; | 1091 | volatile int val; |
1096 | 1092 | ||
@@ -1100,20 +1096,18 @@ void test_exceptions(void) | @@ -1100,20 +1096,18 @@ void test_exceptions(void) | ||
1100 | sigaction(SIGFPE, &act, NULL); | 1096 | sigaction(SIGFPE, &act, NULL); |
1101 | sigaction(SIGILL, &act, NULL); | 1097 | sigaction(SIGILL, &act, NULL); |
1102 | sigaction(SIGSEGV, &act, NULL); | 1098 | sigaction(SIGSEGV, &act, NULL); |
1099 | + sigaction(SIGBUS, &act, NULL); | ||
1103 | sigaction(SIGTRAP, &act, NULL); | 1100 | sigaction(SIGTRAP, &act, NULL); |
1104 | 1101 | ||
1105 | /* test division by zero reporting */ | 1102 | /* test division by zero reporting */ |
1106 | - dump_eip = 0; | ||
1107 | - dump_si_addr = 0; | ||
1108 | - printf("DIVZ exception (currently imprecise):\n"); | 1103 | + printf("DIVZ exception:\n"); |
1109 | if (setjmp(jmp_env) == 0) { | 1104 | if (setjmp(jmp_env) == 0) { |
1110 | /* now divide by zero */ | 1105 | /* now divide by zero */ |
1111 | v1 = 0; | 1106 | v1 = 0; |
1112 | v1 = 2 / v1; | 1107 | v1 = 2 / v1; |
1113 | } | 1108 | } |
1114 | 1109 | ||
1115 | - dump_si_addr = 1; | ||
1116 | - printf("BOUND exception (currently imprecise):\n"); | 1110 | + printf("BOUND exception:\n"); |
1117 | if (setjmp(jmp_env) == 0) { | 1111 | if (setjmp(jmp_env) == 0) { |
1118 | /* bound exception */ | 1112 | /* bound exception */ |
1119 | tab[0] = 1; | 1113 | tab[0] = 1; |
@@ -1121,27 +1115,50 @@ void test_exceptions(void) | @@ -1121,27 +1115,50 @@ void test_exceptions(void) | ||
1121 | asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); | 1115 | asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); |
1122 | } | 1116 | } |
1123 | 1117 | ||
1118 | + printf("segment exceptions:\n"); | ||
1119 | + if (setjmp(jmp_env) == 0) { | ||
1120 | + /* load an invalid segment */ | ||
1121 | + asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1)); | ||
1122 | + } | ||
1123 | + if (setjmp(jmp_env) == 0) { | ||
1124 | + /* null data segment is valid */ | ||
1125 | + asm volatile ("movl %0, %%fs" : : "r" (3)); | ||
1126 | + /* null stack segment */ | ||
1127 | + asm volatile ("movl %0, %%ss" : : "r" (3)); | ||
1128 | + } | ||
1129 | + | ||
1130 | + ldt.entry_number = 1; | ||
1131 | + ldt.base_addr = (unsigned long)&seg_data1; | ||
1132 | + ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; | ||
1133 | + ldt.seg_32bit = 1; | ||
1134 | + ldt.contents = MODIFY_LDT_CONTENTS_DATA; | ||
1135 | + ldt.read_exec_only = 0; | ||
1136 | + ldt.limit_in_pages = 1; | ||
1137 | + ldt.seg_not_present = 1; | ||
1138 | + ldt.useable = 1; | ||
1139 | + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ | ||
1140 | + | ||
1141 | + if (setjmp(jmp_env) == 0) { | ||
1142 | + /* segment not present */ | ||
1143 | + asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); | ||
1144 | + } | ||
1145 | + | ||
1124 | /* test SEGV reporting */ | 1146 | /* test SEGV reporting */ |
1125 | - printf("PF exception (currently imprecise):\n"); | 1147 | + printf("PF exception:\n"); |
1126 | if (setjmp(jmp_env) == 0) { | 1148 | if (setjmp(jmp_env) == 0) { |
1149 | + val = 1; | ||
1127 | /* now store in an invalid address */ | 1150 | /* now store in an invalid address */ |
1128 | *(char *)0x1234 = 1; | 1151 | *(char *)0x1234 = 1; |
1129 | } | 1152 | } |
1130 | 1153 | ||
1131 | /* test SEGV reporting */ | 1154 | /* test SEGV reporting */ |
1132 | - printf("PF exception (currently imprecise):\n"); | 1155 | + printf("PF exception:\n"); |
1133 | if (setjmp(jmp_env) == 0) { | 1156 | if (setjmp(jmp_env) == 0) { |
1157 | + val = 1; | ||
1134 | /* read from an invalid address */ | 1158 | /* read from an invalid address */ |
1135 | v1 = *(char *)0x1234; | 1159 | v1 = *(char *)0x1234; |
1136 | } | 1160 | } |
1137 | 1161 | ||
1138 | - printf("segment GPF exception (currently imprecise):\n"); | ||
1139 | - if (setjmp(jmp_env) == 0) { | ||
1140 | - /* load an invalid segment */ | ||
1141 | - asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); | ||
1142 | - } | ||
1143 | - | ||
1144 | - dump_eip = 1; | ||
1145 | /* test illegal instruction reporting */ | 1162 | /* test illegal instruction reporting */ |
1146 | printf("UD2 exception:\n"); | 1163 | printf("UD2 exception:\n"); |
1147 | if (setjmp(jmp_env) == 0) { | 1164 | if (setjmp(jmp_env) == 0) { |
@@ -1153,6 +1170,18 @@ void test_exceptions(void) | @@ -1153,6 +1170,18 @@ void test_exceptions(void) | ||
1153 | if (setjmp(jmp_env) == 0) { | 1170 | if (setjmp(jmp_env) == 0) { |
1154 | asm volatile ("int $0xfd"); | 1171 | asm volatile ("int $0xfd"); |
1155 | } | 1172 | } |
1173 | + if (setjmp(jmp_env) == 0) { | ||
1174 | + asm volatile ("int $0x01"); | ||
1175 | + } | ||
1176 | + if (setjmp(jmp_env) == 0) { | ||
1177 | + asm volatile (".byte 0xcd, 0x03"); | ||
1178 | + } | ||
1179 | + if (setjmp(jmp_env) == 0) { | ||
1180 | + asm volatile ("int $0x04"); | ||
1181 | + } | ||
1182 | + if (setjmp(jmp_env) == 0) { | ||
1183 | + asm volatile ("int $0x05"); | ||
1184 | + } | ||
1156 | 1185 | ||
1157 | printf("INT3 exception:\n"); | 1186 | printf("INT3 exception:\n"); |
1158 | if (setjmp(jmp_env) == 0) { | 1187 | if (setjmp(jmp_env) == 0) { |