Commit 61a8c4ec3a39cf8547aba056f03574a5fac31fdd

Authored by bellard
1 parent 9746b15b

enter insn fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1135 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
@@ -27,6 +27,7 @@ version 0.6.1: @@ -27,6 +27,7 @@ version 0.6.1:
27 - Floppy fixes for NT4 and NT5 (Mike Nordell) 27 - Floppy fixes for NT4 and NT5 (Mike Nordell)
28 - NT4 IDE fixes (Ben Pfaf, Mike Nordell) 28 - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
29 - SDL Audio support and SB16 fixes (malc) 29 - SDL Audio support and SB16 fixes (malc)
  30 + - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
30 31
31 version 0.6.0: 32 version 0.6.0:
32 33
target-i386/exec.h
@@ -167,6 +167,7 @@ void helper_divl_EAX_T0(uint32_t eip); @@ -167,6 +167,7 @@ void helper_divl_EAX_T0(uint32_t eip);
167 void helper_idivl_EAX_T0(uint32_t eip); 167 void helper_idivl_EAX_T0(uint32_t eip);
168 void helper_cmpxchg8b(void); 168 void helper_cmpxchg8b(void);
169 void helper_cpuid(void); 169 void helper_cpuid(void);
  170 +void helper_enter_level(int level, int data32);
170 void helper_sysenter(void); 171 void helper_sysenter(void);
171 void helper_sysexit(void); 172 void helper_sysexit(void);
172 void helper_rdtsc(void); 173 void helper_rdtsc(void);
target-i386/helper.c
@@ -1068,6 +1068,38 @@ void helper_cpuid(void) @@ -1068,6 +1068,38 @@ void helper_cpuid(void)
1068 } 1068 }
1069 } 1069 }
1070 1070
  1071 +void helper_enter_level(int level, int data32)
  1072 +{
  1073 + uint8_t *ssp;
  1074 + uint32_t esp_mask, esp, ebp;
  1075 +
  1076 + esp_mask = get_sp_mask(env->segs[R_SS].flags);
  1077 + ssp = env->segs[R_SS].base;
  1078 + ebp = EBP;
  1079 + esp = ESP;
  1080 + if (data32) {
  1081 + /* 32 bit */
  1082 + esp -= 4;
  1083 + while (--level) {
  1084 + esp -= 4;
  1085 + ebp -= 4;
  1086 + stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
  1087 + }
  1088 + esp -= 4;
  1089 + stl(ssp + (esp & esp_mask), T1);
  1090 + } else {
  1091 + /* 16 bit */
  1092 + esp -= 2;
  1093 + while (--level) {
  1094 + esp -= 2;
  1095 + ebp -= 2;
  1096 + stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
  1097 + }
  1098 + esp -= 2;
  1099 + stw(ssp + (esp & esp_mask), T1);
  1100 + }
  1101 +}
  1102 +
1071 void helper_lldt_T0(void) 1103 void helper_lldt_T0(void)
1072 { 1104 {
1073 int selector; 1105 int selector;
target-i386/op.c
@@ -695,6 +695,11 @@ void OPPROTO op_cpuid(void) @@ -695,6 +695,11 @@ void OPPROTO op_cpuid(void)
695 helper_cpuid(); 695 helper_cpuid();
696 } 696 }
697 697
  698 +void OPPROTO op_enter_level(void)
  699 +{
  700 + helper_enter_level(PARAM1, PARAM2);
  701 +}
  702 +
698 void OPPROTO op_sysenter(void) 703 void OPPROTO op_sysenter(void)
699 { 704 {
700 helper_sysenter(); 705 helper_sysenter();
target-i386/translate.c
@@ -1690,15 +1690,12 @@ static void gen_popa(DisasContext *s) @@ -1690,15 +1690,12 @@ static void gen_popa(DisasContext *s)
1690 gen_op_mov_reg_T1[OT_WORD + s->dflag][R_ESP](); 1690 gen_op_mov_reg_T1[OT_WORD + s->dflag][R_ESP]();
1691 } 1691 }
1692 1692
1693 -/* NOTE: wrap around in 16 bit not fully handled */  
1694 -/* XXX: check this */  
1695 static void gen_enter(DisasContext *s, int esp_addend, int level) 1693 static void gen_enter(DisasContext *s, int esp_addend, int level)
1696 { 1694 {
1697 - int ot, level1, addend, opsize; 1695 + int ot, opsize;
1698 1696
1699 ot = s->dflag + OT_WORD; 1697 ot = s->dflag + OT_WORD;
1700 level &= 0x1f; 1698 level &= 0x1f;
1701 - level1 = level;  
1702 opsize = 2 << s->dflag; 1699 opsize = 2 << s->dflag;
1703 1700
1704 gen_op_movl_A0_ESP(); 1701 gen_op_movl_A0_ESP();
@@ -1712,19 +1709,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level) @@ -1712,19 +1709,10 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
1712 gen_op_mov_TN_reg[OT_LONG][0][R_EBP](); 1709 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1713 gen_op_st_T0_A0[ot + s->mem_index](); 1710 gen_op_st_T0_A0[ot + s->mem_index]();
1714 if (level) { 1711 if (level) {
1715 - while (level--) {  
1716 - gen_op_addl_A0_im(-opsize);  
1717 - gen_op_addl_T0_im(-opsize);  
1718 - gen_op_st_T0_A0[ot + s->mem_index]();  
1719 - }  
1720 - gen_op_addl_A0_im(-opsize);  
1721 - gen_op_st_T1_A0[ot + s->mem_index](); 1712 + gen_op_enter_level(level, s->dflag);
1722 } 1713 }
1723 gen_op_mov_reg_T1[ot][R_EBP](); 1714 gen_op_mov_reg_T1[ot][R_EBP]();
1724 - addend = -esp_addend;  
1725 - if (level1)  
1726 - addend -= opsize * (level1 + 1);  
1727 - gen_op_addl_T1_im(addend); 1715 + gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
1728 gen_op_mov_reg_T1[ot][R_ESP](); 1716 gen_op_mov_reg_T1[ot][R_ESP]();
1729 } 1717 }
1730 1718
tests/test-i386.c
@@ -1625,7 +1625,55 @@ void test_self_modifying_code(void) @@ -1625,7 +1625,55 @@ void test_self_modifying_code(void)
1625 printf("smc_code2(%d) = %d\n", i, smc_code2(i)); 1625 printf("smc_code2(%d) = %d\n", i, smc_code2(i));
1626 } 1626 }
1627 } 1627 }
1628 - 1628 +
  1629 +int enter_stack[4096];
  1630 +
  1631 +#define TEST_ENTER(size, stack_type, level)\
  1632 +{\
  1633 + int esp_save, esp_val, ebp_val, ebp_save, i;\
  1634 + stack_type *ptr, *stack_end, *stack_ptr;\
  1635 + memset(enter_stack, 0, sizeof(enter_stack));\
  1636 + stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
  1637 + ebp_val = (long)stack_ptr;\
  1638 + for(i=1;i<=32;i++)\
  1639 + *--stack_ptr = i;\
  1640 + esp_val = (long)stack_ptr;\
  1641 + asm("movl %%esp, %[esp_save]\n"\
  1642 + "movl %%ebp, %[ebp_save]\n"\
  1643 + "movl %[esp_val], %%esp\n"\
  1644 + "movl %[ebp_val], %%ebp\n"\
  1645 + "enter" size " $12, $" #level "\n"\
  1646 + "movl %%esp, %[esp_val]\n"\
  1647 + "movl %%ebp, %[ebp_val]\n"\
  1648 + "movl %[esp_save], %%esp\n"\
  1649 + "movl %[ebp_save], %%ebp\n"\
  1650 + : [esp_save] "=r" (esp_save),\
  1651 + [ebp_save] "=r" (ebp_save),\
  1652 + [esp_val] "=r" (esp_val),\
  1653 + [ebp_val] "=r" (ebp_val)\
  1654 + : "[esp_val]" (esp_val),\
  1655 + "[ebp_val]" (ebp_val));\
  1656 + printf("level=%d:\n", level);\
  1657 + printf("esp_val=0x%08lx\n", esp_val - (long)stack_end);\
  1658 + printf("ebp_val=0x%08lx\n", ebp_val - (long)stack_end);\
  1659 + for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
  1660 + printf("%08x\n", ptr[0]);\
  1661 +}
  1662 +
  1663 +static void test_enter(void)
  1664 +{
  1665 + TEST_ENTER("l", uint32_t, 0);
  1666 + TEST_ENTER("l", uint32_t, 1);
  1667 + TEST_ENTER("l", uint32_t, 2);
  1668 + TEST_ENTER("l", uint32_t, 31);
  1669 +
  1670 + TEST_ENTER("w", uint16_t, 0);
  1671 + TEST_ENTER("w", uint16_t, 1);
  1672 + TEST_ENTER("w", uint16_t, 2);
  1673 + TEST_ENTER("w", uint16_t, 31);
  1674 +}
  1675 +
  1676 +
1629 static void *call_end __init_call = NULL; 1677 static void *call_end __init_call = NULL;
1630 1678
1631 int main(int argc, char **argv) 1679 int main(int argc, char **argv)
@@ -1653,5 +1701,6 @@ int main(int argc, char **argv) @@ -1653,5 +1701,6 @@ int main(int argc, char **argv)
1653 test_exceptions(); 1701 test_exceptions();
1654 test_self_modifying_code(); 1702 test_self_modifying_code();
1655 test_single_step(); 1703 test_single_step();
  1704 + test_enter();
1656 return 0; 1705 return 0;
1657 } 1706 }