Commit 3ff0631ed9b993f933c1430c7eae5c8b851bb8d2

Authored by bellard
1 parent b1ba6574

added linux < 2.4.21 vm86 bug workaround - added extensive TF flag test


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@376 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 93 additions and 3 deletions
tests/test-i386.c
... ... @@ -13,6 +13,7 @@
13 13  
14 14 #define TEST_CMOV 0
15 15 #define TEST_FCOMI 0
  16 +//#define LINUX_VM86_IOPL_FIX
16 17  
17 18 #define xglue(x, y) x ## y
18 19 #define glue(x, y) xglue(x, y)
... ... @@ -1106,7 +1107,7 @@ void test_vm86(void)
1106 1107 switch(VM86_TYPE(ret)) {
1107 1108 case VM86_INTx:
1108 1109 {
1109   - int int_num, ah;
  1110 + int int_num, ah, v;
1110 1111  
1111 1112 int_num = VM86_ARG(ret);
1112 1113 if (int_num != 0x21)
... ... @@ -1134,8 +1135,12 @@ void test_vm86(void)
1134 1135 r->eax = (r->eax & ~0xff) | '$';
1135 1136 }
1136 1137 break;
1137   - case 0xff: /* extension: write hex number in edx */
1138   - printf("%08x\n", (int)r->edx);
  1138 + case 0xff: /* extension: write eflags number in edx */
  1139 + v = (int)r->edx;
  1140 +#ifndef LINUX_VM86_IOPL_FIX
  1141 + v &= ~0x3000;
  1142 +#endif
  1143 + printf("%08x\n", v);
1139 1144 break;
1140 1145 default:
1141 1146 unknown_int:
... ... @@ -1356,6 +1361,90 @@ void test_exceptions(void)
1356 1361 printf("val=0x%x\n", val);
1357 1362 }
1358 1363  
  1364 +/* specific precise single step test */
  1365 +void sig_trap_handler(int sig, siginfo_t *info, void *puc)
  1366 +{
  1367 + struct ucontext *uc = puc;
  1368 + printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]);
  1369 +}
  1370 +
  1371 +const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};
  1372 +uint8_t sstep_buf2[4];
  1373 +
  1374 +void test_single_step(void)
  1375 +{
  1376 + struct sigaction act;
  1377 + volatile int val;
  1378 + int i;
  1379 +
  1380 + val = 0;
  1381 + act.sa_sigaction = sig_trap_handler;
  1382 + sigemptyset(&act.sa_mask);
  1383 + act.sa_flags = SA_SIGINFO;
  1384 + sigaction(SIGTRAP, &act, NULL);
  1385 + asm volatile ("pushf\n"
  1386 + "orl $0x00100, (%%esp)\n"
  1387 + "popf\n"
  1388 + "movl $0xabcd, %0\n"
  1389 +
  1390 + /* jmp test */
  1391 + "movl $3, %%ecx\n"
  1392 + "1:\n"
  1393 + "addl $1, %0\n"
  1394 + "decl %%ecx\n"
  1395 + "jnz 1b\n"
  1396 +
  1397 + /* movsb: the single step should stop at each movsb iteration */
  1398 + "movl $sstep_buf1, %%esi\n"
  1399 + "movl $sstep_buf2, %%edi\n"
  1400 + "movl $0, %%ecx\n"
  1401 + "rep movsb\n"
  1402 + "movl $3, %%ecx\n"
  1403 + "rep movsb\n"
  1404 + "movl $1, %%ecx\n"
  1405 + "rep movsb\n"
  1406 +
  1407 + /* cmpsb: the single step should stop at each cmpsb iteration */
  1408 + "movl $sstep_buf1, %%esi\n"
  1409 + "movl $sstep_buf2, %%edi\n"
  1410 + "movl $0, %%ecx\n"
  1411 + "rep cmpsb\n"
  1412 + "movl $4, %%ecx\n"
  1413 + "rep cmpsb\n"
  1414 +
  1415 + /* getpid() syscall: single step should skip one
  1416 + instruction */
  1417 + "movl $20, %%eax\n"
  1418 + "int $0x80\n"
  1419 + "movl $0, %%eax\n"
  1420 +
  1421 + /* when modifying SS, trace is not done on the next
  1422 + instruction */
  1423 + "movl %%ss, %%ecx\n"
  1424 + "movl %%ecx, %%ss\n"
  1425 + "addl $1, %0\n"
  1426 + "movl $1, %%eax\n"
  1427 + "movl %%ecx, %%ss\n"
  1428 + "jmp 1f\n"
  1429 + "addl $1, %0\n"
  1430 + "1:\n"
  1431 + "movl $1, %%eax\n"
  1432 + "pushl %%ecx\n"
  1433 + "popl %%ss\n"
  1434 + "addl $1, %0\n"
  1435 + "movl $1, %%eax\n"
  1436 +
  1437 + "pushf\n"
  1438 + "andl $~0x00100, (%%esp)\n"
  1439 + "popf\n"
  1440 + : "=m" (val)
  1441 + :
  1442 + : "cc", "memory", "eax", "ecx", "esi", "edi");
  1443 + printf("val=%d\n", val);
  1444 + for(i = 0; i < 4; i++)
  1445 + printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);
  1446 +}
  1447 +
1359 1448 /* self modifying code test */
1360 1449 uint8_t code[] = {
1361 1450 0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
... ... @@ -1402,5 +1491,6 @@ int main(int argc, char **argv)
1402 1491 test_vm86();
1403 1492 test_exceptions();
1404 1493 test_self_modifying_code();
  1494 + test_single_step();
1405 1495 return 0;
1406 1496 }
... ...