Commit 3ff0631ed9b993f933c1430c7eae5c8b851bb8d2
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 | } | ... | ... |