about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/aarch64/sem.py12
-rw-r--r--miasm2/arch/x86/sem.py66
-rw-r--r--miasm2/jitter/codegen.py20
-rw-r--r--miasm2/jitter/llvmconvert.py43
-rw-r--r--miasm2/jitter/vm_mngr.h80
5 files changed, 111 insertions, 110 deletions
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index 599cdc98..79c72d32 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -3,8 +3,8 @@ from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.arch.aarch64.arch import mn_aarch64, conds_expr, replace_regs
 from miasm2.arch.aarch64.regs import *
 from miasm2.core.sembuilder import SemBuilder
+from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO
 
-EXCEPT_PRIV_INSN = (1 << 17)
 
 # CPSR: N Z C V
 
@@ -136,7 +136,9 @@ ctx = {"PC": PC,
        "of": of,
        "cond2expr": cond2expr,
        "extend_arg": extend_arg,
-       "m2_expr":m2_expr
+       "m2_expr":m2_expr,
+       "exception_flags": exception_flags,
+       "EXCEPT_DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO,
        }
 
 sbuild = SemBuilder(ctx)
@@ -528,7 +530,11 @@ def msub(arg1, arg2, arg3, arg4):
 
 @sbuild.parse
 def udiv(arg1, arg2, arg3):
-    arg1 = m2_expr.ExprOp('udiv', arg2, arg3)
+    if arg3:
+        arg1 = m2_expr.ExprOp('udiv', arg2, arg3)
+    else:
+        exception_flags = m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO,
+                                          exception_flags.size)
 
 
 @sbuild.parse
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 0312891b..e32b8001 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -23,6 +23,8 @@ from miasm2.arch.x86.arch import mn_x86, repeat_mn, replace_regs
 from miasm2.expression.expression_helper import expr_cmps, expr_cmpu
 from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.core.sembuilder import SemBuilder
+from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_ILLEGAL_INSN, \
+    EXCEPT_PRIV_INSN, EXCEPT_SOFT_BP, EXCEPT_INT_XX
 import math
 import struct
 
@@ -36,22 +38,6 @@ ctx = {'mRAX': mRAX,
        }
 sbuild = SemBuilder(ctx)
 
-# interrupt with eip update after instr
-EXCEPT_SOFT_BP = (1 << 1)
-EXCEPT_INT_XX = (1 << 2)
-
-EXCEPT_BREAKPOINT_INTERN = (1 << 10)
-
-EXCEPT_NUM_UPDT_EIP = (1 << 11)
-# interrupt with eip at instr
-EXCEPT_UNK_MEM_AD = (1 << 12)
-EXCEPT_THROW_SEH = (1 << 13)
-EXCEPT_UNK_EIP = (1 << 14)
-EXCEPT_ACCESS_VIOL = (1 << 14)
-EXCEPT_INT_DIV_BY_ZERO = (1 << 16)
-EXCEPT_PRIV_INSN = (1 << 17)
-EXCEPT_ILLEGAL_INSN = (1 << 18)
-EXCEPT_UNK_MNEMO = (1 << 19)
 
 
 """
@@ -1441,7 +1427,7 @@ def loope(ir, instr, dst):
 # XXX size to do; eflag
 
 
-def div(_, instr, src1):
+def div(ir, instr, src1):
     e = []
     size = src1.size
     if size == 8:
@@ -1461,12 +1447,32 @@ def div(_, instr, src1):
     else:
         e.append(m2_expr.ExprAff(s1, c_r[:size]))
         e.append(m2_expr.ExprAff(s2, c_d[:size]))
-    return e, []
+
+    lbl_div = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+    lbl_except = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+
+    do_div = []
+    do_div += e
+    do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
+    blk_div = IRBlock(lbl_div.name, [do_div])
+
+    do_except = []
+    do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt(
+        EXCEPT_DIV_BY_ZERO, exception_flags.size)))
+    do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
+    blk_except = IRBlock(lbl_except.name, [do_except])
+
+    e = []
+    e.append(m2_expr.ExprAff(ir.IRDst,
+                             m2_expr.ExprCond(src1, lbl_div, lbl_except)))
+
+    return e, [blk_div, blk_except]
 
 
 # XXX size to do; eflag
 
-def idiv(_, instr, src1):
+def idiv(ir, instr, src1):
     e = []
     size = src1.size
 
@@ -1487,7 +1493,27 @@ def idiv(_, instr, src1):
     else:
         e.append(m2_expr.ExprAff(s1, c_r[:size]))
         e.append(m2_expr.ExprAff(s2, c_d[:size]))
-    return e, []
+
+    lbl_div = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+    lbl_except = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+
+    do_div = []
+    do_div += e
+    do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
+    blk_div = IRBlock(lbl_div.name, [do_div])
+
+    do_except = []
+    do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt(
+        EXCEPT_DIV_BY_ZERO, exception_flags.size)))
+    do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
+    blk_except = IRBlock(lbl_except.name, [do_except])
+
+    e = []
+    e.append(m2_expr.ExprAff(ir.IRDst,
+                             m2_expr.ExprCond(src1, lbl_div, lbl_except)))
+
+    return e, [blk_div, blk_except]
 
 
 # XXX size to do; eflag
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index b2398dd2..15f172ee 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -25,7 +25,6 @@ class Attributes(object):
         self.mem_read = False
         self.mem_write = False
         self.set_exception = False
-        self.op_set_exception = False
         self.log_mn = log_mn
         self.log_regs = log_regs
         self.instr = None
@@ -36,8 +35,6 @@ class CGen(object):
     Helper to generate C code for a given AsmBlock
     """
 
-    IMPLICIT_EXCEPTION_OP = set(['umod', 'udiv'])
-
     """
     Translate native assembly block to C
     """
@@ -325,7 +322,7 @@ class CGen(object):
         out = []
         if attrib.mem_read | attrib.mem_write:
             out += (self.CODE_VM_EXCEPTION_POST_INSTR % (self.C_PC)).split('\n')
-        if attrib.set_exception or attrib.op_set_exception:
+        if attrib.set_exception:
             out += (self.CODE_CPU_EXCEPTION_POST_INSTR % (self.C_PC)).split('\n')
 
         if attrib.mem_read | attrib.mem_write:
@@ -437,10 +434,6 @@ class CGen(object):
         if c_prefetch:
             out += self.gen_check_memory_exception(attrib.instr.offset)
 
-        # Check if operator raised exception flags
-        if attrib.op_set_exception:
-            out += self.gen_check_cpu_exception(attrib.instr.offset)
-
         out.append("// Mem updt")
         out += c_mem
 
@@ -462,12 +455,6 @@ class CGen(object):
 
         return out
 
-    def is_exception_operator(self, operator):
-        """Return True if the @op operator can raise a runtime exception"""
-
-        return any(operator.startswith(except_op)
-                   for except_op in self.IMPLICIT_EXCEPTION_OP)
-
     def get_caracteristics(self, assignblk, attrib):
         """
         Set the carateristics in @attrib according to the @assignblk
@@ -479,10 +466,6 @@ class CGen(object):
         attrib.set_exception = self.ir_arch.arch.regs.exception_flags in assignblk
 
         element_read = assignblk.get_r(mem_read=True)
-        # Check implicit exception raising
-        attrib.op_set_exception = any(self.is_exception_operator(operator)
-                                      for elem in assignblk.values()
-                                      for operator in m2_expr.get_expr_ops(elem))
         # Check mem read
         attrib.mem_read = any(isinstance(expr, m2_expr.ExprMem)
                               for expr in element_read)
@@ -513,7 +496,6 @@ class CGen(object):
                 attrib.instr = instr
                 instr_attrib.mem_read |= attrib.mem_read
                 instr_attrib.mem_write |= attrib.mem_write
-                instr_attrib.op_set_exception |= attrib.op_set_exception
                 instr_attrib.set_exception |= attrib.set_exception
 
         return instr_attrib, irblocks_attributes
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index e7a1d6bc..ae018c18 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -242,23 +242,6 @@ class LLVMContext_JIT(LLVMContext):
                                               "args": [LLVMType.IntType(k),
                                                        LLVMType.IntType(k)]}})
 
-        for k in [16, 32, 64]:
-            self.add_fc({"imod%s" % k: {"ret": LLVMType.IntType(k),
-                                        "args": [p8,
-                                                 LLVMType.IntType(k),
-                                                 LLVMType.IntType(k)]}})
-            self.add_fc({"idiv%s" % k: {"ret": LLVMType.IntType(k),
-                                        "args": [p8,
-                                                 LLVMType.IntType(k),
-                                                 LLVMType.IntType(k)]}})
-            self.add_fc({"umod%s" % k: {"ret": LLVMType.IntType(k),
-                                        "args": [p8,
-                                                 LLVMType.IntType(k),
-                                                 LLVMType.IntType(k)]}})
-            self.add_fc({"udiv%s" % k: {"ret": LLVMType.IntType(k),
-                                        "args": [p8,
-                                                 LLVMType.IntType(k),
-                                                 LLVMType.IntType(k)]}})
 
     def add_log_functions(self):
         "Add functions for state logging"
@@ -745,11 +728,21 @@ class LLVMFunction():
                 return ret
 
             if op in ["imod", "idiv", "umod", "udiv"]:
-                fc_ptr = self.mod.get_global(
-                    "%s%s" % (op, expr.args[0].size))
-                args_casted = [self.add_ir(arg) for arg in expr.args]
-                args = [self.local_vars["vmcpu"]] + args_casted
-                ret = builder.call(fc_ptr, args)
+                assert len(expr.args) == 2
+
+                arg_b = self.add_ir(expr.args[1])
+                arg_a = self.add_ir(expr.args[0])
+
+                if op == "imod":
+                    callback = builder.srem
+                elif op == "idiv":
+                    callback = builder.sdiv
+                elif op == "umod":
+                    callback = builder.urem
+                elif op == "udiv":
+                    callback = builder.udiv
+
+                ret = callback(arg_a, arg_b)
                 self.update_cache(expr, ret)
                 return ret
 
@@ -1020,8 +1013,6 @@ class LLVMFunction():
             fc_ptr = self.mod.get_global("check_invalid_code_blocs")
             self.builder.call(fc_ptr, [self.local_vars["vmmngr"]])
             self.check_memory_exception(next_instr, restricted_exception=False)
-        if attrib.set_exception or attrib.op_set_exception:
-            self.check_cpu_exception(next_instr, restricted_exception=False)
 
         if attrib.mem_read | attrib.mem_write:
             fc_ptr = self.mod.get_global("reset_memory_access")
@@ -1146,10 +1137,6 @@ class LLVMFunction():
                 self.check_memory_exception(instr.offset,
                                             restricted_exception=True)
 
-            # Check operation exception
-            if attributes[index].op_set_exception:
-                self.check_cpu_exception(instr.offset, restricted_exception=True)
-
             # Update the memory
             for dst, src in values.iteritems():
                 if isinstance(dst, m2_expr.ExprMem):
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index 912b105e..74ad49ad 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -224,55 +224,55 @@ unsigned int rcr_rez_op(unsigned int size, unsigned int a, unsigned int b, unsig
 
 
 #define UDIV(sizeA)						\
-    uint ## sizeA ## _t udiv ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
-	    {								\
-	    uint ## sizeA ## _t r;						\
-	    if (b == 0) {						\
-		    vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO;	\
-		    return 0;						\
-	    }								\
-	    r = a/b;							\
-	    return r;							\
-	    }
+	uint ## sizeA ## _t udiv ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
+	{								\
+		uint ## sizeA ## _t r;					\
+		if (b == 0) {						\
+			fprintf(stderr, "Should not happen\n");		\
+			exit(0);					\
+		}							\
+		r = a/b;						\
+		return r;						\
+	}
 
 
 #define UMOD(sizeA)						\
-    uint ## sizeA ## _t umod ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
-	    {								\
-	    uint ## sizeA ## _t r;						\
-	    if (b == 0) {						\
-		    vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO;	\
-		    return 0;						\
-	    }								\
-	    r = a%b;							\
-	    return r;							\
-	    }
+	uint ## sizeA ## _t umod ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \
+	{								\
+		uint ## sizeA ## _t r;					\
+		if (b == 0) {						\
+			fprintf(stderr, "Should not happen\n");		\
+			exit(0);					\
+		}							\
+		r = a%b;						\
+		return r;						\
+	}
 
 
 #define IDIV(sizeA)						\
-    int ## sizeA ## _t idiv ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \
-	    {								\
-	    int ## sizeA ## _t r;						\
-	    if (b == 0) {						\
-		    vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO;	\
-		    return 0;						\
-	    }								\
-	    r = a/b;							\
-	    return r;							\
-	    }
+	int ## sizeA ## _t idiv ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \
+	{								\
+		int ## sizeA ## _t r;					\
+		if (b == 0) {						\
+			fprintf(stderr, "Should not happen\n");		\
+			exit(0);					\
+		}							\
+		r = a/b;						\
+		return r;						\
+	}
 
 
 #define IMOD(sizeA)						\
-    int ## sizeA ## _t imod ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \
-	    {								\
-	    int ## sizeA ## _t r;						\
-	    if (b == 0) {						\
-		    vmcpu->exception_flags |= EXCEPT_INT_DIV_BY_ZERO;	\
-		    return 0;						\
-	    }								\
-	    r = a%b;							\
-	    return r;							\
-	    }
+	int ## sizeA ## _t imod ## sizeA (vm_cpu_t* vmcpu, int ## sizeA ## _t a, int ## sizeA ## _t b) \
+	{								\
+		int ## sizeA ## _t r;					\
+		if (b == 0) {						\
+			fprintf(stderr, "Should not happen\n");		\
+			exit(0);					\
+		}							\
+		r = a%b;						\
+		return r;						\
+	}
 
 
 void memory_access_list_init(struct memory_access_list * access);