about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2015-02-20 14:02:20 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2015-02-20 14:02:20 +0100
commit82d3e73cd19f3638265d35f765cdab1dc13d1ddb (patch)
treed2c4a568c9fd9aea904b92e1bcbeb770e8dddbb5
parent736befb2b6fab02e601eae392a9969ac91f2caa3 (diff)
downloadmiasm-82d3e73cd19f3638265d35f765cdab1dc13d1ddb.tar.gz
miasm-82d3e73cd19f3638265d35f765cdab1dc13d1ddb.zip
X86: fix bsr/bsf behaviour as issued in PR #79
-rw-r--r--miasm2/arch/x86/sem.py51
-rw-r--r--miasm2/ir/translators/C.py8
-rw-r--r--miasm2/jitter/vm_mngr.c19
3 files changed, 45 insertions, 33 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index bc98baf3..928554cb 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -2496,32 +2496,41 @@ def aas(ir, instr, ):
     return e, []
 
 
-def bsf(ir, instr, a, b):
-    lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode)
-
-    e = [m2_expr.ExprAff(zf, m2_expr.ExprCond(b, m2_expr.ExprInt_from(zf, 0),
-                                              m2_expr.ExprInt_from(zf, 1)))]
+def bsr_bsf(ir, instr, a, b, op_name):
+    """
+    IF SRC == 0
+        ZF = 1
+        DEST is left unchanged
+    ELSE
+        ZF = 0
+        DEST = @op_name(SRC)
+    """
+    lbl_src_null = m2_expr.ExprId(ir.gen_label(), instr.mode)
+    lbl_src_not_null = m2_expr.ExprId(ir.gen_label(), instr.mode)
+    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode)
 
-    e_do = []
-    e_do.append(m2_expr.ExprAff(a, m2_expr.ExprOp('bsf', b)))
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
-    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b, lbl_do, lbl_skip)))
-    return e, [irbloc(lbl_do.name, [e_do])]
+    aff_dst = m2_expr.ExprAff(ir.IRDst, lbl_next)
+    e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b,
+                                                    lbl_src_not_null,
+                                                    lbl_src_null))]
+    e_src_null = []
+    e_src_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt_from(zf, 1)))
+    # XXX destination is undefined
+    e_src_null.append(aff_dst)
 
+    e_src_not_null = []
+    e_src_not_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt_from(zf, 0)))
+    e_src_not_null.append(m2_expr.ExprAff(a, m2_expr.ExprOp(op_name, b)))
+    e_src_not_null.append(aff_dst)
 
-def bsr(ir, instr, a, b):
-    lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode)
+    return e, [irbloc(lbl_src_null.name, [e_src_null]),
+               irbloc(lbl_src_not_null.name, [e_src_not_null])]
 
-    e = [m2_expr.ExprAff(zf, m2_expr.ExprCond(b, m2_expr.ExprInt_from(zf, 0),
-                                              m2_expr.ExprInt_from(zf, 1)))]
+def bsf(ir, instr, a, b):
+    return bsr_bsf(ir, instr, a, b, "bsf")
 
-    e_do = []
-    e_do.append(m2_expr.ExprAff(a, m2_expr.ExprOp('bsr', b)))
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
-    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b, lbl_do, lbl_skip)))
-    return e, [irbloc(lbl_do.name, [e_do])]
+def bsr(ir, instr, a, b):
+    return bsr_bsf(ir, instr, a, b, "bsr")
 
 
 def arpl(ir, instr, a, b):
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index a730b1d8..007f8378 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -59,6 +59,10 @@ class TranslatorC(Translator):
             if expr.op == 'parity':
                 return "parity(%s&0x%x)" % (cls.from_expr(expr.args[0]),
                                             size2mask(expr.args[0].size))
+            elif expr.op in ['bsr', 'bsf']:
+                return "x86_%s(%s, 0x%x)" % (expr.op,
+                                             cls.from_expr(expr.args[0]),
+                                             expr.args[0].size)
             elif expr.op == '!':
                 return "(~ %s)&0x%x" % (cls.from_expr(expr.args[0]),
                                         size2mask(expr.args[0].size))
@@ -102,10 +106,6 @@ class TranslatorC(Translator):
                                                    cls.from_expr(expr.args[0]),
                                                    cls.from_expr(expr.args[1]),
                                                    size2mask(expr.args[0].size))
-            elif expr.op in ['bsr', 'bsf']:
-                return 'my_%s(%s, %s)' % (expr.op,
-                                          cls.from_expr(expr.args[0]),
-                                          cls.from_expr(expr.args[1]))
             elif (expr.op.startswith('cpuid') or
                   expr.op.startswith("fcom")  or
                   expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]):
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index 188f0372..057c10be 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -915,26 +915,29 @@ int rcr_cf_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf
 {
 	return rcl_cf_op(size, a, size+1-b, cf);
 }
-unsigned int my_bsr(unsigned int a, unsigned int b)
+
+unsigned int x86_bsr(uint64_t src, unsigned int size)
 {
 	int i;
 
-	for (i=31; i>=0; i--){
-		if (b & (1<<i))
+	for (i=size-1; i>=0; i--){
+		if (src & (1<<i))
 			return i;
 	}
-	return a;
+	fprintf(stderr, "sanity check error bsr\n");
+	exit(0);
 }
 
-unsigned int my_bsf(unsigned int a, unsigned int b)
+unsigned int x86_bsf(uint64_t src, unsigned int size)
 {
 	int i;
 
-	for (i=0; i<32; i++){
-		if (b & (1<<i))
+	for (i=0; i<size; i++){
+		if (src & (1<<i))
 			return i;
 	}
-	return a;
+	fprintf(stderr, "sanity check error bsf\n");
+	exit(0);
 }