about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/aarch64/ira.py7
-rw-r--r--miasm2/arch/arm/ira.py7
-rw-r--r--miasm2/arch/mips32/jit.py2
-rw-r--r--miasm2/arch/msp430/ira.py14
-rw-r--r--miasm2/arch/x86/ira.py14
-rw-r--r--miasm2/jitter/codegen.py34
-rw-r--r--miasm2/jitter/jitcore_cc_base.py2
-rw-r--r--miasm2/jitter/jitcore_llvm.py4
-rw-r--r--miasm2/jitter/llvmconvert.py14
-rw-r--r--miasm2/jitter/vm_mngr_py.c8
-rw-r--r--test/jitter/test_post_instr.py46
-rwxr-xr-xtest/test_all.py1
12 files changed, 89 insertions, 64 deletions
diff --git a/miasm2/arch/aarch64/ira.py b/miasm2/arch/aarch64/ira.py
index ada2e028..5a89e910 100644
--- a/miasm2/arch/aarch64/ira.py
+++ b/miasm2/arch/aarch64/ira.py
@@ -24,13 +24,6 @@ class ir_a_aarch64l(ir_a_aarch64l_base):
         ir_a_aarch64l_base.__init__(self, symbol_pool)
         self.ret_reg = self.arch.regs.X0
 
-    # for test XXX TODO
-    def set_dead_regs(self, irblock):
-        irblock.rw[-1][1].add(self.arch.regs.zf)
-        irblock.rw[-1][1].add(self.arch.regs.nf)
-        irblock.rw[-1][1].add(self.arch.regs.of)
-        irblock.rw[-1][1].add(self.arch.regs.cf)
-
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
 
diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py
index 760e6d90..bfa9bad2 100644
--- a/miasm2/arch/arm/ira.py
+++ b/miasm2/arch/arm/ira.py
@@ -21,13 +21,6 @@ class ir_a_arml(ir_a_arml_base):
         ir_a_arml_base.__init__(self, symbol_pool)
         self.ret_reg = self.arch.regs.R0
 
-    # for test XXX TODO
-    def set_dead_regs(self, irblock):
-        irblock.rw[-1][1].add(self.arch.regs.zf)
-        irblock.rw[-1][1].add(self.arch.regs.nf)
-        irblock.rw[-1][1].add(self.arch.regs.of)
-        irblock.rw[-1][1].add(self.arch.regs.cf)
-
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
 
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index 0ba531f1..bfa9c5fd 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -63,7 +63,7 @@ class mipsCGen(CGen):
         """
 
         lbl = self.get_block_post_label(block)
-        out = (self.CODE_RETURN_NO_EXCEPTION % (lbl.name,
+        out = (self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl),
                                                 self.C_PC,
                                                 m2_expr.ExprId('branch_dst_irdst'),
                                                 m2_expr.ExprId('branch_dst_irdst'),
diff --git a/miasm2/arch/msp430/ira.py b/miasm2/arch/msp430/ira.py
index 0dc63c61..0f88facc 100644
--- a/miasm2/arch/msp430/ira.py
+++ b/miasm2/arch/msp430/ira.py
@@ -16,20 +16,6 @@ class ir_a_msp430(ir_a_msp430_base):
     def __init__(self, symbol_pool=None):
         ir_a_msp430_base.__init__(self, symbol_pool)
 
-    # for test XXX TODO
-    def set_dead_regs(self, irblock):
-        irblock.rw[-1][1].add(self.arch.regs.zf)
-        irblock.rw[-1][1].add(self.arch.regs.nf)
-        irblock.rw[-1][1].add(self.arch.regs.of)
-        irblock.rw[-1][1].add(self.arch.regs.cf)
-
-        irblock.rw[-1][1].add(self.arch.regs.res)
-        irblock.rw[-1][1].add(self.arch.regs.scg1)
-        irblock.rw[-1][1].add(self.arch.regs.scg0)
-        irblock.rw[-1][1].add(self.arch.regs.osc)
-        irblock.rw[-1][1].add(self.arch.regs.cpuoff)
-        irblock.rw[-1][1].add(self.arch.regs.gie)
-
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
 
diff --git a/miasm2/arch/x86/ira.py b/miasm2/arch/x86/ira.py
index 74aa0203..1fcaaa52 100644
--- a/miasm2/arch/x86/ira.py
+++ b/miasm2/arch/x86/ira.py
@@ -12,23 +12,9 @@ class ir_a_x86_16(ir_x86_16, ira):
         ir_x86_16.__init__(self, symbol_pool)
         self.ret_reg = self.arch.regs.AX
 
-    # for test XXX TODO
-    def set_dead_regs(self, irblock):
-        irblock.rw[-1][1].add(self.arch.regs.zf)
-        irblock.rw[-1][1].add(self.arch.regs.of)
-        irblock.rw[-1][1].add(self.arch.regs.pf)
-        irblock.rw[-1][1].add(self.arch.regs.cf)
-        irblock.rw[-1][1].add(self.arch.regs.nf)
-        irblock.rw[-1][1].add(self.arch.regs.af)
-
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
 
-    def add_unused_regs(self):
-        leaves = [self.blocks[label] for label in self.g.leafs()]
-        for irblock in leaves:
-            self.set_dead_regs(irblock)
-
 class ir_a_x86_32(ir_x86_32, ir_a_x86_16):
 
     def __init__(self, symbol_pool=None):
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index 9d005451..09a6fecf 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -65,7 +65,7 @@ class CGen(object):
 
     CODE_CPU_EXCEPTION_POST_INSTR = r"""
     if (CPU_exception_flag) {
-        %s = %s;
+        %s = DST_value;
         BlockDst->address = DST_value;
         return JIT_RET_EXCEPTION;
     }
@@ -75,7 +75,7 @@ class CGen(object):
     check_memory_breakpoint(&(jitcpu->pyvm->vm_mngr));
     check_invalid_code_blocs(&(jitcpu->pyvm->vm_mngr));
     if (VM_exception_flag) {
-        %s = %s;
+        %s = DST_value;
         BlockDst->address = DST_value;
         return JIT_RET_EXCEPTION;
     }
@@ -106,6 +106,11 @@ class CGen(object):
 
         self.C_PC = self.id_to_c(self.PC)
 
+    @staticmethod
+    def label_to_jitlabel(lbl):
+        assert lbl.offset is not None
+        return "jitblock_%X" % lbl.offset
+
     def dst_to_c(self, src):
         if not isinstance(src, m2_expr.Expr):
             src = m2_expr.ExprInt(src, self.PC.size)
@@ -296,13 +301,12 @@ class CGen(object):
                 '%s' % ret,
                 '%s' % retb], dst2index
 
-    def gen_post_instr_checks(self, attrib, dst):
+    def gen_post_instr_checks(self, attrib):
         out = []
-        dst = self.dst_to_c(dst)
         if attrib.mem_read | attrib.mem_write:
-            out += (self.CODE_VM_EXCEPTION_POST_INSTR % (self.C_PC, dst)).split('\n')
+            out += (self.CODE_VM_EXCEPTION_POST_INSTR % (self.C_PC)).split('\n')
         if attrib.set_exception or attrib.op_set_exception:
-            out += (self.CODE_CPU_EXCEPTION_POST_INSTR % (self.C_PC, dst)).split('\n')
+            out += (self.CODE_CPU_EXCEPTION_POST_INSTR % (self.C_PC)).split('\n')
 
         if attrib.mem_read | attrib.mem_write:
             out.append("reset_memory_access(&(jitcpu->pyvm->vm_mngr));")
@@ -340,12 +344,12 @@ class CGen(object):
             # (consecutive instructions)
             lbl = self.ir_arch.symbol_pool.getby_offset_create(dst)
             out += self.gen_post_code(attrib)
-            out += self.gen_post_instr_checks(attrib, dst)
-            out.append('goto %s;' % lbl.name)
+            out += self.gen_post_instr_checks(attrib)
+            out.append('goto %s;' % self.label_to_jitlabel(lbl))
         else:
             out += self.gen_post_code(attrib)
             out.append('BlockDst->address = DST_value;')
-            out += self.gen_post_instr_checks(attrib, dst)
+            out += self.gen_post_instr_checks(attrib)
             out.append('\t\treturn JIT_RET_NO_EXCEPTION;')
         return out
 
@@ -497,7 +501,7 @@ class CGen(object):
         instr_offsets = [line.offset for line in block.lines]
         instr_offsets.append(self.get_block_post_label(block).offset)
         lbl_start = self.ir_arch.symbol_pool.getby_offset_create(instr_offsets[0])
-        return (self.CODE_INIT % lbl_start.name).split("\n"), instr_offsets
+        return (self.CODE_INIT % self.label_to_jitlabel(lbl_start)).split("\n"), instr_offsets
 
     def gen_irblock(self, attrib, instr_offsets, instr, irblock):
         """
@@ -535,7 +539,7 @@ class CGen(object):
 
         lbl = self.get_block_post_label(block)
         dst = self.dst_to_c(lbl.offset)
-        code = self.CODE_RETURN_NO_EXCEPTION % (lbl.name, self.C_PC, dst, dst)
+        code = self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl), self.C_PC, dst, dst)
         return code.split('\n')
 
     def gen_c(self, block, log_mn=False, log_regs=False):
@@ -558,8 +562,12 @@ class CGen(object):
                 self.ir_arch.irbloc_fix_regs_for_mode(
                     irblock, self.ir_arch.attrib)
 
-                out.append("%-40s // %.16X %s" %
-                           (str(irblock.label.name) + ":", instr.offset, instr))
+                if irblock.label.offset is None:
+                    out.append("%-40s // %.16X %s" %
+                               (str(irblock.label.name) + ":", instr.offset, instr))
+                else:
+                    out.append("%-40s // %.16X %s" %
+                               (self.label_to_jitlabel(irblock.label) + ":", instr.offset, instr))
                 if index == 0:
                     out += self.gen_pre_code(attrib)
                 out += self.gen_irblock(attrib, instr_offsets, instr, irblock)
diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py
index ae8a5dc2..0ca2392d 100644
--- a/miasm2/jitter/jitcore_cc_base.py
+++ b/miasm2/jitter/jitcore_cc_base.py
@@ -90,7 +90,7 @@ class JitCore_Cc_Base(JitCore):
         Generate function name from @label
         @label: AsmLabel instance
         """
-        return "block_%s" % label.name
+        return "block_%s" % self.codegen.label_to_jitlabel(label)
 
     def gen_c_code(self, label, block):
         """
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py
index d082dd79..7765ad39 100644
--- a/miasm2/jitter/jitcore_llvm.py
+++ b/miasm2/jitter/jitcore_llvm.py
@@ -82,7 +82,7 @@ class JitCore_LLVM(jitcore.JitCore):
 
         if not os.access(fname_out, os.R_OK):
             # Build a function in the context
-            func = LLVMFunction(self.context, block.label.name)
+            func = LLVMFunction(self.context, LLVMFunction.canonize_label_name(block.label))
 
             # Set log level
             func.log_regs = self.log_regs
@@ -113,7 +113,7 @@ class JitCore_LLVM(jitcore.JitCore):
 
         else:
             # The cache file exists: function can be loaded from cache
-            ptr = self.context.get_ptr_from_cache(fname_out, block.label.name)
+            ptr = self.context.get_ptr_from_cache(fname_out, LLVMFunction.canonize_label_name(block.label))
 
         # Store a pointer on the function jitted code
         self.lbl2jitbloc[block.label.offset] = ptr
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 85000935..b2e1e957 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -503,15 +503,19 @@ class LLVMFunction():
             var_casted = var
         self.builder.ret(var_casted)
 
-    def canonize_label_name(self, label):
+    @staticmethod
+    def canonize_label_name(label):
         """Canonize @label names to a common form.
         @label: str or asmlabel instance"""
         if isinstance(label, str):
             return label
-        elif isinstance(label, m2_asmblock.AsmLabel):
-            return "label_%s" % label.name
-        elif m2_asmblock.expr_is_label(label):
-            return "label_%s" % label.name.name
+        if m2_asmblock.expr_is_label(label):
+            label = label.name
+        if isinstance(label, m2_asmblock.AsmLabel):
+            if label.offset is None:
+                return "label_%s" % label.name
+            else:
+                return "label_%X" % label.offset
         else:
             raise ValueError("label must either be str or asmlabel")
 
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index e8c8715e..b53e098a 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -262,6 +262,14 @@ PyObject* vm_add_memory_breakpoint(VmMngr* self, PyObject* args)
 	PyGetInt(access, b_access);
 
 	add_memory_breakpoint(&self->vm_mngr, b_ad, b_size, b_access);
+
+	/* Raise exception in the following pattern:
+	   - set_mem(XXX)
+	   - add_memory_breakpoint(XXX)
+	   -> Here, there is a pending breakpoint not raise
+	 */
+	check_memory_breakpoint(&self->vm_mngr);
+
 	Py_INCREF(Py_None);
 	return Py_None;
 }
diff --git a/test/jitter/test_post_instr.py b/test/jitter/test_post_instr.py
new file mode 100644
index 00000000..ceba469d
--- /dev/null
+++ b/test/jitter/test_post_instr.py
@@ -0,0 +1,46 @@
+from miasm2.analysis.machine import Machine
+from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, EXCEPT_BREAKPOINT_INTERN, EXCEPT_ACCESS_VIOL
+import sys
+
+machine = Machine("x86_32")
+jitter = machine.jitter(sys.argv[1])
+
+# Prepare stack and reset memory accesses to avoid an exception
+jitter.vm.add_memory_page(0x10000, PAGE_READ|PAGE_WRITE, "\x00"*0x1000, "stack")
+print jitter.vm
+
+jitter.cpu.ESP = 0x10000 + 0x1000
+jitter.push_uint32_t(0x0)
+jitter.push_uint32_t(0x1337beef)
+
+jitter.vm.reset_memory_access()
+print hex(jitter.vm.get_exception())
+
+# Add code, and keep memory write pending
+jitter.vm.add_memory_page(0x1000, PAGE_READ|PAGE_WRITE, "\x00"*0x1000, "code page")
+
+# MOV EAX, 0x11223344
+# RET
+jitter.vm.set_mem(0x1000, "B844332211C3".decode('hex'))
+
+jitter.jit.log_mn = True
+jitter.jit.log_regs = True
+
+def do_not_raise_me(jitter):
+    raise ValueError("Should not be here")
+
+jitter.exceptions_handler.callbacks[EXCEPT_BREAKPOINT_INTERN] = []
+jitter.add_exception_handler(EXCEPT_BREAKPOINT_INTERN,
+                             do_not_raise_me)
+jitter.vm.add_memory_breakpoint(0x11000-4, 4, 7)
+
+# The memory write pending will raise automod execption
+# The RET should not re evalueate PC @ [ESP+4]
+jitter.init_run(0x1000)
+try:
+    jitter.continue_run()
+except AssertionError:
+    assert jitter.vm.get_exception() == EXCEPT_ACCESS_VIOL
+except RuntimeError:
+    assert sys.argv[1] == 'python'
+    assert jitter.vm.get_exception() == EXCEPT_ACCESS_VIOL
diff --git a/test/test_all.py b/test/test_all.py
index dc17c19b..9b3f2dc1 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -341,6 +341,7 @@ for i, test_args in enumerate(test_args):
 for script in ["jitload.py",
                "vm_mngr.py",
                "jit_options.py",
+               "test_post_instr.py",
                ]:
     for engine in ArchUnitTest.jitter_engines:
         testset += RegressionTest([script, engine], base_dir="jitter",