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) { | ... | ... |