about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/x86/arch.py25
-rw-r--r--miasm2/arch/x86/sem.py10
-rw-r--r--miasm2/ir/symbexec.py66
-rw-r--r--test/arch/x86/arch.py11
-rwxr-xr-xtest/arch/x86/unit/mn_cpuid.py21
-rwxr-xr-xtest/test_all.py1
6 files changed, 96 insertions, 38 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 90d0fcef..edbe9874 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -2445,6 +2445,8 @@ class x86_rm_reg_noarg(object):
         if p.v_opmode() == 64 or p.rex_p.value == 1:
             if not hasattr(p, 'sx') and (hasattr(p, 'w8') and p.w8.value == 0):
                 r = gpregs08_64
+            elif p.rex_r.value == 1:
+                v |= 8
         self.expr = r.expr[v]
         return True
 
@@ -2526,6 +2528,16 @@ class x86_reg(x86_rm_reg):
         self.parent.rex_b.value = v
 
 
+class x86_reg_modrm(x86_rm_reg):
+
+    def getrexsize(self):
+        return self.parent.rex_r.value
+
+    def setrexsize(self, v):
+        self.parent.rex_r.value = v
+
+
+
 class x86_reg_noarg(x86_rm_reg_noarg):
 
     def getrexsize(self):
@@ -3176,6 +3188,10 @@ mod_mem = bs(l=2, cls=(bs_mem,), fname="mod")
 
 rmreg = bs(l=3, cls=(x86_rm_reg, ), order =1, fname = "reg")
 reg = bs(l=3, cls=(x86_reg, ), order =1, fname = "reg")
+
+reg_modrm = bs(l=3, cls=(x86_reg_modrm, ), order =1, fname = "reg")
+
+
 regnoarg = bs(l=3, default_val="000", order=1, fname="reg")
 segm = bs(l=3, cls=(x86_rm_segm, ), order =1, fname = "reg")
 crreg = bs(l=3, cls=(x86_rm_cr, ), order =1, fname = "reg")
@@ -3690,7 +3706,7 @@ addop("movq", [bs8(0x0f), bs8(0xd6), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm_m64), [rm_arg_xmm_m64, xmm_reg])
 
 addop("movmskps", [bs8(0x0f), bs8(0x50), no_xmm_pref] +
-      rmmod(reg, rm_arg_xmm_reg))
+      rmmod(reg_modrm, rm_arg_xmm_reg))
 
 
 addop("addss", [bs8(0x0f), bs8(0x58), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32))
@@ -4194,6 +4210,9 @@ addop("psllw", [bs8(0x0f), bs8(0xf1), no_xmm_pref] +
 addop("psllw", [bs8(0x0f), bs8(0xf1), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
 
+addop("pslldq", [bs8(0x0f), bs8(0x73), pref_66] +
+      rmmod(d7, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
 
 addop("pmaxub", [bs8(0x0f), bs8(0xde), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm))
@@ -4331,9 +4350,9 @@ addop("sqrtss", [bs8(0x0f), bs8(0x51), pref_f3] +
       rmmod(xmm_reg, rm_arg_xmm_m32))
 
 addop("pmovmskb", [bs8(0x0f), bs8(0xd7), no_xmm_pref] +
-      rmmod(reg, rm_arg_mm_reg))
+      rmmod(reg_modrm, rm_arg_mm_reg))
 addop("pmovmskb", [bs8(0x0f), bs8(0xd7), pref_66] +
-      rmmod(reg, rm_arg_xmm_reg))
+      rmmod(reg_modrm, rm_arg_xmm_reg))
 
 addop("shufps", [bs8(0x0f), bs8(0xc6), no_xmm_pref] +
       rmmod(xmm_reg, rm_arg_xmm) + [u08])
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index ea5830e3..df5a07a0 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3627,6 +3627,15 @@ def pslld(ir, instr, a, b):
 def psllq(ir, instr, a, b):
     return ps_rl_ll(ir, instr, a, b, "<<",  64)
 
+def pslldq(ir, instr, a, b):
+    assert b.is_int()
+    e = []
+    count = int(b)
+    if count > 15:
+        return [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size))], []
+    else:
+        return [m2_expr.ExprAff(a, a << m2_expr.ExprInt(8*count, a.size))], []
+
 
 def iret(ir, instr):
     """IRET implementation
@@ -4361,6 +4370,7 @@ mnemo_func = {'mov': mov,
               "psllw": psllw,
               "pslld": pslld,
               "psllq": psllq,
+              "pslldq": pslldq,
 
               "pmaxub": pmaxub,
               "pmaxuw": pmaxuw,
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index fd8413fc..8e04c45b 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -126,8 +126,13 @@ class symbexec(object):
         ptr, size = expr.arg, expr.size
         ret = self.find_mem_by_addr(ptr)
         if not ret:
-            out = []
             overlaps = self.get_mem_overlapping(expr)
+            if not overlaps:
+                if self.func_read and ptr.is_int():
+                    expr = self.func_read(expr)
+                return expr
+
+            out = []
             off_base = 0
             for off, mem in overlaps:
                 if off >= 0:
@@ -141,48 +146,39 @@ class symbexec(object):
                     new_off_base = off_base + new_size + off * 8
                     out.append((tmp, off_base, new_off_base))
                     off_base = new_off_base
-            if out:
-                missing_slice = self.rest_slice(out, 0, size)
-                for slice_start, slice_stop in missing_slice:
-                    ptr = self.expr_simp(ptr + m2_expr.ExprInt(slice_start / 8, ptr.size))
-                    mem = m2_expr.ExprMem(ptr, slice_stop - slice_start)
-                    out.append((mem, slice_start, slice_stop))
-                out.sort(key=lambda x: x[1])
-                args = [expr for (expr, _, _) in out]
-                tmp = m2_expr.ExprSlice(m2_expr.ExprCompose(*args), 0, size)
-                tmp = self.expr_simp(tmp)
-                return tmp
-
-
-            if self.func_read and isinstance(ptr, m2_expr.ExprInt):
-                return self.func_read(expr)
-            else:
-                return expr
+
+            missing_slice = self.rest_slice(out, 0, size)
+            for slice_start, slice_stop in missing_slice:
+                ptr = self.expr_simp(ptr + m2_expr.ExprInt(slice_start / 8, ptr.size))
+                mem = m2_expr.ExprMem(ptr, slice_stop - slice_start)
+                if self.func_read and ptr.is_int():
+                    mem = self.func_read(mem)
+                out.append((mem, slice_start, slice_stop))
+            out.sort(key=lambda x: x[1])
+            args = [expr for (expr, _, _) in out]
+            ret = self.expr_simp(m2_expr.ExprCompose(*args)[:size])
+            return ret
+
         # bigger lookup
         if size > ret.size:
             rest = size
-            ptr = ptr
             out = []
-            ptr_index = 0
             while rest:
                 mem = self.find_mem_by_addr(ptr)
                 if mem is None:
-                    value = m2_expr.ExprMem(ptr, 8)
-                    mem = value
-                    diff_size = 8
+                    mem = m2_expr.ExprMem(ptr, 8)
+                    if self.func_read and ptr.is_int():
+                        value = self.func_read(mem)
+                    else:
+                        value = mem
                 elif rest >= mem.size:
                     value = self.symbols[mem]
-                    diff_size = mem.size
                 else:
-                    diff_size = rest
-                    value = self.symbols[mem][0:diff_size]
-                out.append((value, ptr_index, ptr_index + diff_size))
-                ptr_index += diff_size
-                rest -= diff_size
+                    value = self.symbols[mem][:rest]
+                out.append(value)
+                rest -= value.size
                 ptr = self.expr_simp(ptr + m2_expr.ExprInt(mem.size / 8, ptr.size))
-            out.sort(key=lambda x: x[1])
-            args = [expr for (expr, _, _) in out]
-            ret = self.expr_simp(m2_expr.ExprCompose(*args))
+            ret = self.expr_simp(m2_expr.ExprCompose(*out))
             return ret
         # part lookup
         ret = self.expr_simp(self.symbols[ret][:size])
@@ -406,9 +402,9 @@ class symbexec(object):
                 for new_mem, new_val in diff_mem:
                     self.symbols[new_mem] = new_val
         src_o = self.expr_simp(src)
-        self.symbols[dst] = src_o
-        if dst == src_o:
-            del self.symbols[dst]
+        if dst != src_o:
+            # Avoid X = X
+            self.symbols[dst] = src_o
         if isinstance(dst, m2_expr.ExprMem):
             if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
                 self.func_write(self, dst, src_o)
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index e6797da2..b0ea7cb4 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -2328,6 +2328,8 @@ reg_tests = [
 
     (m64, "00000000    MOVMSKPS   EAX, XMM2",
      "0f50c2"),
+    (m64, "00000000    MOVMSKPS   R8D, XMM2",
+     "440f50c2"),
 
     (m32, "00000000    ADDSS      XMM2, DWORD PTR [ECX]",
      "f30f5811"),
@@ -2725,6 +2727,9 @@ reg_tests = [
     (m32, "00000000    PSLLW      XMM6, 0x5",
     "660F71F605"),
 
+    (m64, "00000000    PSLLDQ     XMM2, 0x1",
+    "660F73Fa01"),
+
 
     (m32, "00000000    PSLLQ      MM2, QWORD PTR [EDX]",
     "0FF312"),
@@ -2919,6 +2924,12 @@ reg_tests = [
     (m32, "00000000    PMOVMSKB   EAX, XMM7",
      "660FD7C7"),
 
+    (m64, "XXXXXXXX    PMOVMSKB   R8D, XMM2",
+    "66440fd7c2"),
+    (m64, "XXXXXXXX    PMOVMSKB   EAX, XMM2",
+    "660fd7c2"),
+
+
     (m64, "00000000    SHUFPS     XMM0, XMM6, 0x44",
      "0fc6c644"),
     (m64, "00000000    SHUFPD     XMM0, XMM6, 0x44",
diff --git a/test/arch/x86/unit/mn_cpuid.py b/test/arch/x86/unit/mn_cpuid.py
new file mode 100755
index 00000000..026de207
--- /dev/null
+++ b/test/arch/x86/unit/mn_cpuid.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python2
+
+import sys
+
+from asm_test import Asm_Test_32
+
+class Test_CPUID(Asm_Test_32):
+    """Check for cpuid support (and not for arbitrary returned values)"""
+    TXT = '''
+    main:
+       XOR EAX, EAX
+       CPUID
+       RET
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0xa
+
+
+if __name__ == "__main__":
+    [test(*sys.argv[1:])() for test in [Test_CPUID]]
diff --git a/test/test_all.py b/test/test_all.py
index e49ce514..ab9e4b9b 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -77,6 +77,7 @@ for script in ["x86/sem.py",
                "x86/unit/mn_pmovmskb.py",
                "x86/unit/mn_pushpop.py",
                "x86/unit/mn_seh.py",
+               "x86/unit/mn_cpuid.py",
                "arm/arch.py",
                "arm/sem.py",
                "aarch64/unit/mn_ubfm.py",