diff mbox

[v2,08/17] x86emul: fold/eliminate some local variables

Message ID 59BAB974020000780017B39C@prv-mh.provo.novell.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Beulich Sept. 14, 2017, 3:16 p.m. UTC
Make i switch-wide (at once making it unsigned, as it should have been)
and introduce n (for immediate use in enter and aam/aad handling).
Eliminate on-stack arrays in pusha/popa handling. Use ea.val instead of
a custom variable in bound handling.

No (intended) functional change.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

Comments

George Dunlap Oct. 6, 2017, 2:21 p.m. UTC | #1
On 09/14/2017 04:16 PM, Jan Beulich wrote:
> Make i switch-wide (at once making it unsigned, as it should have been)
> and introduce n (for immediate use in enter and aam/aad handling).
> Eliminate on-stack arrays in pusha/popa handling. Use ea.val instead of
> a custom variable in bound handling.
> 
> No (intended) functional change.
> 
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

This patch doesn't seem to apply either to tip, or to the state of the
branch at the time it was sent (15 September) -- although a quick scan
wasn't able to determine what git (and emacs diff mode) didn't like.

 -George
George Dunlap Oct. 6, 2017, 2:43 p.m. UTC | #2
On 09/14/2017 04:16 PM, Jan Beulich wrote:
> Make i switch-wide (at once making it unsigned, as it should have been)
> and introduce n (for immediate use in enter and aam/aad handling).
> Eliminate on-stack arrays in pusha/popa handling. Use ea.val instead of
> a custom variable in bound handling.
> 
> No (intended) functional change.
> 
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> 
> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -3238,6 +3238,7 @@ x86_emulate(
>          struct segment_register cs, sreg;
>          struct cpuid_leaf cpuid_leaf;
>          uint64_t msr_val;
> +        unsigned int i, n;
>          unsigned long dummy;
>  
>      case 0x00 ... 0x05: add: /* add */
> @@ -3370,47 +3371,45 @@ x86_emulate(
>              goto done;
>          break;
>  
> -    case 0x60: /* pusha */ {
> -        int i;
> -        unsigned int regs[] = {
> -            _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
> -            _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
> -
> +    case 0x60: /* pusha */
>          fail_if(!ops->write);
> +        ea.val = _regs.esp;
>          for ( i = 0; i < 8; i++ )
> +        {
> +            void *reg = decode_register(i, &_regs, 0);
> +
>              if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
> -                                  &regs[i], op_bytes, ctxt)) != 0 )
> -            goto done;
> +                                  reg != &_regs.esp ? reg : &ea.val,
> +                                  op_bytes, ctxt)) != 0 )
> +                goto done;
> +        }
>          break;
> -    }
> -
> -    case 0x61: /* popa */ {
> -        int i;
> -        unsigned int dummy_esp, *regs[] = {
> -            &_regs.edi, &_regs.esi, &_regs.ebp, &dummy_esp,
> -            &_regs.ebx, &_regs.edx, &_regs.ecx, &_regs.eax };
>  
> +    case 0x61: /* popa */
>          for ( i = 0; i < 8; i++ )
>          {
> +            void *reg = decode_register(7 - i, &_regs, 0);
> +
>              if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
>                                    &dst.val, op_bytes, ctxt, ops)) != 0 )
>                  goto done;
> +            if ( reg == &_regs.r(sp) )
> +                continue;
>              if ( op_bytes == 2 )
> -                *(uint16_t *)regs[i] = (uint16_t)dst.val;
> +                *(uint16_t *)reg = dst.val;
>              else
> -                *regs[i] = dst.val; /* 64b: zero-ext done by read_ulong() */
> +                *(unsigned long *)reg = dst.val;
>          }
>          break;
> -    }
>  
>      case 0x62: /* bound */ {
> -        unsigned long src_val2;
>          int lb, ub, idx;
> +
>          generate_exception_if(src.type != OP_MEM, EXC_UD);
>          if ( (rc = read_ulong(src.mem.seg, truncate_ea(src.mem.off + op_bytes),

This is the bit where the context is wrong; is this meant to be applied
on top of my AFL series?

 -George
Jan Beulich Oct. 6, 2017, 2:47 p.m. UTC | #3
>>> On 06.10.17 at 16:21, <george.dunlap@citrix.com> wrote:
> On 09/14/2017 04:16 PM, Jan Beulich wrote:
>> Make i switch-wide (at once making it unsigned, as it should have been)
>> and introduce n (for immediate use in enter and aam/aad handling).
>> Eliminate on-stack arrays in pusha/popa handling. Use ea.val instead of
>> a custom variable in bound handling.
>> 
>> No (intended) functional change.
>> 
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> 
> This patch doesn't seem to apply either to tip, or to the state of the
> branch at the time it was sent (15 September) -- although a quick scan
> wasn't able to determine what git (and emacs diff mode) didn't like.

Oh, I didn't notice it has a contextual dependency on
"x86emul/fuzz: add rudimentary limit checking", which I have in
my queue ahead of this series (I've really been expecting it to
go in any day, but sadly it still lacks a review or ack).

Jan
diff mbox

Patch

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3238,6 +3238,7 @@  x86_emulate(
         struct segment_register cs, sreg;
         struct cpuid_leaf cpuid_leaf;
         uint64_t msr_val;
+        unsigned int i, n;
         unsigned long dummy;
 
     case 0x00 ... 0x05: add: /* add */
@@ -3370,47 +3371,45 @@  x86_emulate(
             goto done;
         break;
 
-    case 0x60: /* pusha */ {
-        int i;
-        unsigned int regs[] = {
-            _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
-            _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
-
+    case 0x60: /* pusha */
         fail_if(!ops->write);
+        ea.val = _regs.esp;
         for ( i = 0; i < 8; i++ )
+        {
+            void *reg = decode_register(i, &_regs, 0);
+
             if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
-                                  &regs[i], op_bytes, ctxt)) != 0 )
-            goto done;
+                                  reg != &_regs.esp ? reg : &ea.val,
+                                  op_bytes, ctxt)) != 0 )
+                goto done;
+        }
         break;
-    }
-
-    case 0x61: /* popa */ {
-        int i;
-        unsigned int dummy_esp, *regs[] = {
-            &_regs.edi, &_regs.esi, &_regs.ebp, &dummy_esp,
-            &_regs.ebx, &_regs.edx, &_regs.ecx, &_regs.eax };
 
+    case 0x61: /* popa */
         for ( i = 0; i < 8; i++ )
         {
+            void *reg = decode_register(7 - i, &_regs, 0);
+
             if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
                                   &dst.val, op_bytes, ctxt, ops)) != 0 )
                 goto done;
+            if ( reg == &_regs.r(sp) )
+                continue;
             if ( op_bytes == 2 )
-                *(uint16_t *)regs[i] = (uint16_t)dst.val;
+                *(uint16_t *)reg = dst.val;
             else
-                *regs[i] = dst.val; /* 64b: zero-ext done by read_ulong() */
+                *(unsigned long *)reg = dst.val;
         }
         break;
-    }
 
     case 0x62: /* bound */ {
-        unsigned long src_val2;
         int lb, ub, idx;
+
         generate_exception_if(src.type != OP_MEM, EXC_UD);
         if ( (rc = read_ulong(src.mem.seg, truncate_ea(src.mem.off + op_bytes),
-                              &src_val2, op_bytes, ctxt, ops)) )
+                              &ea.val, op_bytes, ctxt, ops)) )
             goto done;
-        ub  = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2;
+        ub  = (op_bytes == 2) ? (int16_t)ea.val   : (int32_t)ea.val;
         lb  = (op_bytes == 2) ? (int16_t)src.val  : (int32_t)src.val;
         idx = (op_bytes == 2) ? (int16_t)dst.val  : (int32_t)dst.val;
         generate_exception_if((idx < lb) || (idx > ub), EXC_BR);
@@ -3967,10 +3966,7 @@  x86_emulate(
         dst.val = src.val;
         break;
 
-    case 0xc8: /* enter imm16,imm8 */ {
-        uint8_t depth = imm2 & 31;
-        int i;
-
+    case 0xc8: /* enter imm16,imm8 */
         dst.type = OP_REG;
         dst.bytes = (mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes;
         dst.reg = (unsigned long *)&_regs.r(bp);
@@ -3980,9 +3976,10 @@  x86_emulate(
             goto done;
         dst.val = _regs.r(sp);
 
-        if ( depth > 0 )
+        n = imm2 & 31;
+        if ( n )
         {
-            for ( i = 1; i < depth; i++ )
+            for ( i = 1; i < n; i++ )
             {
                 unsigned long ebp, temp_data;
                 ebp = truncate_word(_regs.r(bp) - i*dst.bytes, ctxt->sp_size/8);
@@ -3999,7 +3996,6 @@  x86_emulate(
 
         sp_pre_dec(src.val);
         break;
-    }
 
     case 0xc9: /* leave */
         /* First writeback, to %%esp. */
@@ -4094,28 +4090,21 @@  x86_emulate(
         goto grp2;
 
     case 0xd4: /* aam */
-    case 0xd5: /* aad */ {
-        unsigned int base = (uint8_t)src.val;
-
+    case 0xd5: /* aad */
+        n = (uint8_t)src.val;
         if ( b & 0x01 )
-        {
-            uint16_t ax = _regs.ax;
-
-            _regs.ax = (uint8_t)(ax + ((ax >> 8) * base));
-        }
+            _regs.ax = (uint8_t)(_regs.al + (_regs.ah * n));
         else
         {
-            uint8_t al = _regs.al;
-
-            generate_exception_if(!base, EXC_DE);
-            _regs.ax = ((al / base) << 8) | (al % base);
+            generate_exception_if(!n, EXC_DE);
+            _regs.al = _regs.al % n;
+            _regs.ah = _regs.al / n;
         }
         _regs.eflags &= ~(X86_EFLAGS_SF | X86_EFLAGS_ZF | X86_EFLAGS_PF);
         _regs.eflags |= !_regs.al ? X86_EFLAGS_ZF : 0;
         _regs.eflags |= ((int8_t)_regs.al < 0) ? X86_EFLAGS_SF : 0;
         _regs.eflags |= even_parity(_regs.al) ? X86_EFLAGS_PF : 0;
         break;
-    }
 
     case 0xd6: /* salc */
         _regs.al = (_regs.eflags & X86_EFLAGS_CF) ? 0xff : 0x00;