about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2015-11-13 10:33:50 +0100
committerAjax <commial@gmail.com>2015-11-13 10:33:50 +0100
commit18bcd354ee95348227d97bca9fbd5acfb9476d56 (patch)
tree149cf160bc8e7cc81fe9d543787bae02aa7f3138
parent2982c0635d94545c25072f28de915c1334312039 (diff)
downloadmiasm-18bcd354ee95348227d97bca9fbd5acfb9476d56.tar.gz
miasm-18bcd354ee95348227d97bca9fbd5acfb9476d56.zip
x86/sem: fix shld for 'undefined behavior'
-rw-r--r--miasm2/arch/x86/sem.py22
1 files changed, 16 insertions, 6 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 308090e4..5d2df31f 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -482,7 +482,12 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False):
 
     res = m2_expr.ExprOp(op, a, shifter)
     cf_from_dst = m2_expr.ExprOp(op, a,
-                                 (shifter - m2_expr.ExprInt_from(a, 1)))[:1]
+                                 (shifter - m2_expr.ExprInt_from(a, 1)))
+    if left:
+        cf_from_dst = cf_from_dst.msb()
+    else:
+        cf_from_dst = cf_from_dst[:1]
+
     i1 = m2_expr.ExprInt(1, size=a.size)
     if c is not None:
         # There is a source for new bits
@@ -491,11 +496,12 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False):
 
         # An overflow can occured, emulate the 'undefined behavior'
         # Overflow behavior if (shift / size % 2)
-        cond_overflow = ((c - m2_expr.ExprInt(1, size=c.size)) &
-                         m2_expr.ExprInt(a.size, c.size))
+        base_cond_overflow = c if left else (c - m2_expr.ExprInt(1, size=c.size))
+        cond_overflow = base_cond_overflow & m2_expr.ExprInt(a.size, c.size)
         if left:
-            mask = ~mask
-        mask = m2_expr.ExprCond(cond_overflow, ~mask, mask)
+            mask = m2_expr.ExprCond(cond_overflow, mask, ~mask)
+        else:
+            mask = m2_expr.ExprCond(cond_overflow, ~mask, mask)
 
         # Build res with dst and src
         res = ((m2_expr.ExprOp(op, a, shifter) & mask) |
@@ -503,7 +509,11 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False):
 
         # Overflow case: cf come from src (bit number shifter % size)
         cf_from_src = m2_expr.ExprOp(op, b,
-                                     (c.zeroExtend(b.size) & m2_expr.ExprInt(a.size - 1, b.size)) - i1)[:1]
+                                     (c.zeroExtend(b.size) & m2_expr.ExprInt(a.size - 1, b.size)) - i1)
+        if left:
+            cf_from_src = cf_from_src.msb()
+        else:
+            cf_from_src = cf_from_src[:1]
         new_cf = m2_expr.ExprCond(cond_overflow, cf_from_src, cf_from_dst)
 
     else: