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 | 1063 | #endif |
1064 | 1064 | |
1065 | 1065 | jmp_buf jmp_env; |
1066 | -int dump_eip; | |
1067 | -int dump_si_addr; | |
1068 | 1066 | int v1; |
1069 | 1067 | int tab[2]; |
1070 | 1068 | |
... | ... | @@ -1074,23 +1072,21 @@ void sig_handler(int sig, siginfo_t *info, void *puc) |
1074 | 1072 | |
1075 | 1073 | printf("si_signo=%d si_errno=%d si_code=%d", |
1076 | 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 | 1077 | printf("\n"); |
1082 | 1078 | |
1083 | 1079 | printf("trapno=0x%02x err=0x%08x", |
1084 | 1080 | uc->uc_mcontext.gregs[REG_TRAPNO], |
1085 | 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 | 1083 | printf("\n"); |
1089 | 1084 | longjmp(jmp_env, 1); |
1090 | 1085 | } |
1091 | 1086 | |
1092 | 1087 | void test_exceptions(void) |
1093 | 1088 | { |
1089 | + struct modify_ldt_ldt_s ldt; | |
1094 | 1090 | struct sigaction act; |
1095 | 1091 | volatile int val; |
1096 | 1092 | |
... | ... | @@ -1100,20 +1096,18 @@ void test_exceptions(void) |
1100 | 1096 | sigaction(SIGFPE, &act, NULL); |
1101 | 1097 | sigaction(SIGILL, &act, NULL); |
1102 | 1098 | sigaction(SIGSEGV, &act, NULL); |
1099 | + sigaction(SIGBUS, &act, NULL); | |
1103 | 1100 | sigaction(SIGTRAP, &act, NULL); |
1104 | 1101 | |
1105 | 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 | 1104 | if (setjmp(jmp_env) == 0) { |
1110 | 1105 | /* now divide by zero */ |
1111 | 1106 | v1 = 0; |
1112 | 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 | 1111 | if (setjmp(jmp_env) == 0) { |
1118 | 1112 | /* bound exception */ |
1119 | 1113 | tab[0] = 1; |
... | ... | @@ -1121,27 +1115,50 @@ void test_exceptions(void) |
1121 | 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 | 1146 | /* test SEGV reporting */ |
1125 | - printf("PF exception (currently imprecise):\n"); | |
1147 | + printf("PF exception:\n"); | |
1126 | 1148 | if (setjmp(jmp_env) == 0) { |
1149 | + val = 1; | |
1127 | 1150 | /* now store in an invalid address */ |
1128 | 1151 | *(char *)0x1234 = 1; |
1129 | 1152 | } |
1130 | 1153 | |
1131 | 1154 | /* test SEGV reporting */ |
1132 | - printf("PF exception (currently imprecise):\n"); | |
1155 | + printf("PF exception:\n"); | |
1133 | 1156 | if (setjmp(jmp_env) == 0) { |
1157 | + val = 1; | |
1134 | 1158 | /* read from an invalid address */ |
1135 | 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 | 1162 | /* test illegal instruction reporting */ |
1146 | 1163 | printf("UD2 exception:\n"); |
1147 | 1164 | if (setjmp(jmp_env) == 0) { |
... | ... | @@ -1153,6 +1170,18 @@ void test_exceptions(void) |
1153 | 1170 | if (setjmp(jmp_env) == 0) { |
1154 | 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 | 1186 | printf("INT3 exception:\n"); |
1158 | 1187 | if (setjmp(jmp_env) == 0) { | ... | ... |