direct-io.hg

changeset 14346:e39964673c6f

xen: Fix emulator to use default segment SS for ESP/EBP references.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Mar 12 11:00:44 2007 +0000 (2007-03-12)
parents bcd8d0387cbf
children 94fcbb52bde2
files xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate.c	Mon Mar 12 10:10:42 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate.c	Mon Mar 12 11:00:44 2007 +0000
     1.3 @@ -726,7 +726,7 @@ x86_emulate(
     1.4      uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
     1.5      unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes;
     1.6      unsigned int lock_prefix = 0, rep_prefix = 0;
     1.7 -    int rc = X86EMUL_OKAY;
     1.8 +    int override_seg = -1, rc = X86EMUL_OKAY;
     1.9      struct operand src, dst;
    1.10  
    1.11      /* Data operand effective address (usually computed from ModRM). */
    1.12 @@ -758,22 +758,22 @@ x86_emulate(
    1.13              ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6);
    1.14              break;
    1.15          case 0x2e: /* CS override */
    1.16 -            ea.mem.seg = x86_seg_cs;
    1.17 +            override_seg = x86_seg_cs;
    1.18              break;
    1.19          case 0x3e: /* DS override */
    1.20 -            ea.mem.seg = x86_seg_ds;
    1.21 +            override_seg = x86_seg_ds;
    1.22              break;
    1.23          case 0x26: /* ES override */
    1.24 -            ea.mem.seg = x86_seg_es;
    1.25 +            override_seg = x86_seg_es;
    1.26              break;
    1.27          case 0x64: /* FS override */
    1.28 -            ea.mem.seg = x86_seg_fs;
    1.29 +            override_seg = x86_seg_fs;
    1.30              break;
    1.31          case 0x65: /* GS override */
    1.32 -            ea.mem.seg = x86_seg_gs;
    1.33 +            override_seg = x86_seg_gs;
    1.34              break;
    1.35          case 0x36: /* SS override */
    1.36 -            ea.mem.seg = x86_seg_ss;
    1.37 +            override_seg = x86_seg_ss;
    1.38              break;
    1.39          case 0xf0: /* LOCK */
    1.40              lock_prefix = 1;
    1.41 @@ -839,14 +839,35 @@ x86_emulate(
    1.42              /* 16-bit ModR/M decode. */
    1.43              switch ( modrm_rm )
    1.44              {
    1.45 -            case 0: ea.mem.off = _regs.ebx + _regs.esi; break;
    1.46 -            case 1: ea.mem.off = _regs.ebx + _regs.edi; break;
    1.47 -            case 2: ea.mem.off = _regs.ebp + _regs.esi; break;
    1.48 -            case 3: ea.mem.off = _regs.ebp + _regs.edi; break;
    1.49 -            case 4: ea.mem.off = _regs.esi; break;
    1.50 -            case 5: ea.mem.off = _regs.edi; break;
    1.51 -            case 6: ea.mem.off = _regs.ebp; break;
    1.52 -            case 7: ea.mem.off = _regs.ebx; break;
    1.53 +            case 0:
    1.54 +                ea.mem.off = _regs.ebx + _regs.esi;
    1.55 +                break;
    1.56 +            case 1:
    1.57 +                ea.mem.off = _regs.ebx + _regs.edi;
    1.58 +                break;
    1.59 +            case 2:
    1.60 +                ea.mem.seg = x86_seg_ss;
    1.61 +                ea.mem.off = _regs.ebp + _regs.esi;
    1.62 +                break;
    1.63 +            case 3:
    1.64 +                ea.mem.seg = x86_seg_ss;
    1.65 +                ea.mem.off = _regs.ebp + _regs.edi;
    1.66 +                break;
    1.67 +            case 4:
    1.68 +                ea.mem.off = _regs.esi;
    1.69 +                break;
    1.70 +            case 5:
    1.71 +                ea.mem.off = _regs.edi;
    1.72 +                break;
    1.73 +            case 6:
    1.74 +                if ( modrm_mod == 0 )
    1.75 +                    break;
    1.76 +                ea.mem.seg = x86_seg_ss;
    1.77 +                ea.mem.off = _regs.ebp;
    1.78 +                break;
    1.79 +            case 7:
    1.80 +                ea.mem.off = _regs.ebx;
    1.81 +                break;
    1.82              }
    1.83              switch ( modrm_mod )
    1.84              {
    1.85 @@ -876,10 +897,20 @@ x86_emulate(
    1.86                  ea.mem.off <<= (sib >> 6) & 3;
    1.87                  if ( (modrm_mod == 0) && ((sib_base & 7) == 5) )
    1.88                      ea.mem.off += insn_fetch_type(int32_t);
    1.89 -                else if ( (sib_base == 4) && !twobyte && (b == 0x8f) )
    1.90 -                    /* POP <rm> must have its EA calculated post increment. */
    1.91 -                    ea.mem.off += _regs.esp +
    1.92 -                        ((mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes);
    1.93 +                else if ( sib_base == 4 )
    1.94 +                {
    1.95 +                    ea.mem.seg  = x86_seg_ss;
    1.96 +                    ea.mem.off += _regs.esp;
    1.97 +                    if ( !twobyte && (b == 0x8f) )
    1.98 +                        /* POP <rm> computes its EA post increment. */
    1.99 +                        ea.mem.off += ((mode_64bit() && (op_bytes == 4))
   1.100 +                                       ? 8 : op_bytes);
   1.101 +                }
   1.102 +                else if ( sib_base == 5 )
   1.103 +                {
   1.104 +                    ea.mem.seg  = x86_seg_ss;
   1.105 +                    ea.mem.off += _regs.ebp;
   1.106 +                }
   1.107                  else
   1.108                      ea.mem.off += *(long*)decode_register(sib_base, &_regs, 0);
   1.109              }
   1.110 @@ -887,6 +918,8 @@ x86_emulate(
   1.111              {
   1.112                  modrm_rm |= (rex_prefix & 1) << 3;
   1.113                  ea.mem.off = *(long *)decode_register(modrm_rm, &_regs, 0);
   1.114 +                if ( (modrm_rm == 5) && (modrm_mod != 0) )
   1.115 +                    ea.mem.seg = x86_seg_ss;
   1.116              }
   1.117              switch ( modrm_mod )
   1.118              {
   1.119 @@ -920,6 +953,9 @@ x86_emulate(
   1.120          }
   1.121      }
   1.122  
   1.123 +    if ( override_seg != -1 )
   1.124 +        ea.mem.seg = override_seg;
   1.125 +
   1.126      /* Special instructions do their own operand decoding. */
   1.127      if ( (d & DstMask) == ImplicitOps )
   1.128          goto special_insn;