about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/aarch64/ira.py2
-rw-r--r--miasm2/arch/arm/ira.py2
-rw-r--r--miasm2/arch/mips32/ira.py2
-rw-r--r--miasm2/arch/msp430/ira.py2
-rw-r--r--miasm2/arch/x86/ira.py41
-rw-r--r--miasm2/ir/analysis.py11
-rw-r--r--miasm2/ir/ir.py91
7 files changed, 89 insertions, 62 deletions
diff --git a/miasm2/arch/aarch64/ira.py b/miasm2/arch/aarch64/ira.py
index 1c2d0ae9..3441483c 100644
--- a/miasm2/arch/aarch64/ira.py
+++ b/miasm2/arch/aarch64/ira.py
@@ -54,7 +54,7 @@ class ir_a_aarch64l(ir_a_aarch64l_base):
             # CALL
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
-            irs = self.call_effects(pc_val)
+            irs = self.call_effects(pc_val, l)
             irs.append(AssignBlock([ExprAff(self.IRDst,
                                             ExprId(lbl, size=self.pc.size))]))
             nbloc = irbloc(new_lbl, irs)
diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py
index 4af7b753..d888d598 100644
--- a/miasm2/arch/arm/ira.py
+++ b/miasm2/arch/arm/ira.py
@@ -52,7 +52,7 @@ class ir_a_arml(ir_a_arml_base):
             # CALL
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
-            irs = self.call_effects(pc_val)
+            irs = self.call_effects(pc_val, l)
             irs.append(AssignBlock([ExprAff(self.IRDst,
                                             ExprId(lbl, size=self.pc.size))]))
             nbloc = irbloc(new_lbl, irs)
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index fd951791..ec63c8c7 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -40,7 +40,7 @@ class ir_a_mips32l(ir_mips32l, ira):
             # CALL
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
-            irs = self.call_effects(pc_val)
+            irs = self.call_effects(pc_val, l)
             irs.append(AssignBlock([ExprAff(self.IRDst,
                                             ExprId(lbl, size=self.pc.size))]))
             nbloc = irbloc(new_lbl, irs)
diff --git a/miasm2/arch/msp430/ira.py b/miasm2/arch/msp430/ira.py
index 2d6fdc8f..bf777775 100644
--- a/miasm2/arch/msp430/ira.py
+++ b/miasm2/arch/msp430/ira.py
@@ -50,7 +50,7 @@ class ir_a_msp430(ir_a_msp430_base):
             l = bloc.lines[-1]
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
-            irs = self.call_effects(pc_val)
+            irs = self.call_effects(pc_val, l)
             irs.append(AssignBlock([ExprAff(self.IRDst,
                                             ExprId(lbl, size=self.pc.size))]))
             nbloc = irbloc(new_lbl, irs)
diff --git a/miasm2/arch/x86/ira.py b/miasm2/arch/x86/ira.py
index bc09add4..d772d9fc 100644
--- a/miasm2/arch/x86/ira.py
+++ b/miasm2/arch/x86/ira.py
@@ -31,37 +31,14 @@ class ir_a_x86_16(ir_x86_16, ira):
         for b in leaves:
             self.set_dead_regs(b)
 
-    def post_add_bloc(self, bloc, ir_blocs):
-        ir.post_add_bloc(self, bloc, ir_blocs)
-        if not bloc.lines:
-            return
-        l = bloc.lines[-1]
-        sub_call_dst = None
-        if not l.is_subcall():
-            return
-        sub_call_dst = l.args[0]
-        if expr_is_label(sub_call_dst):
-            sub_call_dst = sub_call_dst.name
-        for irb in ir_blocs:
-            l = irb.lines[-1]
-            sub_call_dst = None
-            if not l.is_subcall():
-                continue
-            sub_call_dst = l.args[0]
-            if expr_is_label(sub_call_dst):
-                sub_call_dst = sub_call_dst.name
-            lbl = bloc.get_next()
-            new_lbl = self.gen_label()
-            irs = self.call_effects(l.args[0])
-            irs.append(AssignBlock([ExprAff(self.IRDst,
-                                            ExprId(lbl, size=self.pc.size))]))
-
-            nbloc = irbloc(new_lbl, irs)
-            nbloc.lines = [l] * len(irs)
-            self.blocs[new_lbl] = nbloc
-            irb.dst = ExprId(new_lbl, size=self.pc.size)
-        return
-
+    def pre_add_instr(self, block, instr, irb_cur, ir_blocks_all, gen_pc_update):
+        if not instr.is_subcall():
+            return irb_cur
+        call_effects = self.call_effects(instr.args[0], instr)
+        for assignblk in call_effects:
+            irb_cur.irs.append(assignblk)
+            irb_cur.lines.append(instr)
+        return None
 
 class ir_a_x86_32(ir_x86_32, ir_a_x86_16):
 
@@ -91,7 +68,7 @@ class ir_a_x86_64(ir_x86_64, ir_a_x86_16):
         ir_x86_64.__init__(self, symbol_pool)
         self.ret_reg = self.arch.regs.RAX
 
-    def call_effects(self, ad):
+    def call_effects(self, ad, instr):
         return [AssignBlock([ExprAff(self.ret_reg, ExprOp('call_func_ret', ad,
                                                           self.sp,
                                                           self.arch.regs.RCX,
diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py
index 52fbf2e9..0913019b 100644
--- a/miasm2/ir/analysis.py
+++ b/miasm2/ir/analysis.py
@@ -28,11 +28,16 @@ class ira(ir):
         """Returns ids of all registers used in the IR"""
         return self.arch.regs.all_regs_ids + [self.IRDst]
 
-    def call_effects(self, ad):
-        """
-        Default simulation of a function call to @ad
+    def call_effects(self, ad, instr):
+        """Default modelisation of a function call to @ad. This may be used to:
+
+        * insert dependencies to arguments (stack base, registers, ...)
+        * add some side effects (stack clean, return value, ...)
+
         @ad: (Expr) address of the called function
+        @instr: native instruction which is responsible of the call
         """
+
         return [AssignBlock(
             [ExprAff(self.ret_reg, ExprOp('call_func_ret', ad, self.sp)),
              ExprAff(self.sp, ExprOp(
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index 52230da7..0a7d68ce 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -363,29 +363,74 @@ class ir(object):
                                                   )]))
         c.lines.append(l)
 
-    def add_bloc(self, bloc, gen_pc_updt=False):
-        c = None
-        ir_blocs_all = []
-        for l in bloc.lines:
-            if c is None:
-                label = self.get_instr_label(l)
-                c = irbloc(label, [], [])
-                ir_blocs_all.append(c)
-            assignblk, ir_blocs_extra = self.instr2ir(l)
-
-            if gen_pc_updt is not False:
-                self.gen_pc_update(c, l)
-
-            c.irs.append(assignblk)
-            c.lines.append(l)
-
-            if ir_blocs_extra:
-                for b in ir_blocs_extra:
-                    b.lines = [l] * len(b.irs)
-                ir_blocs_all += ir_blocs_extra
-                c = None
-        self.post_add_bloc(bloc, ir_blocs_all)
-        return ir_blocs_all
+    def pre_add_instr(self, block, instr, irb_cur, ir_blocks_all, gen_pc_updt):
+        """Function called before adding an instruction from the the native @block to
+        the current irbloc.
+
+        Returns None if the addition needs an irblock split, @irb_cur in other
+        cases.
+
+        @block: native block source
+        @instr: native instruction
+        @irb_cur: current irbloc
+        @ir_blocks_all: list of additional effects
+        @gen_pc_updt: insert PC update effects between instructions
+
+        """
+
+        return irb_cur
+
+    def add_instr_to_irblock(self, block, instr, irb_cur, ir_blocks_all, gen_pc_updt):
+        """
+        Add the IR effects of an instruction to the current irblock.
+
+        Returns None if the addition needs an irblock split, @irb_cur in other
+        cases.
+
+        @block: native block source
+        @instr: native instruction
+        @irb_cur: current irbloc
+        @ir_blocks_all: list of additional effects
+        @gen_pc_updt: insert PC update effects between instructions
+        """
+
+        irb_cur = self.pre_add_instr(block, instr, irb_cur, ir_blocks_all, gen_pc_updt)
+        if irb_cur is None:
+            return None
+
+        assignblk, ir_blocs_extra = self.instr2ir(instr)
+
+        if gen_pc_updt is not False:
+            self.gen_pc_update(irb_cur, instr)
+
+        irb_cur.irs.append(assignblk)
+        irb_cur.lines.append(instr)
+
+        if ir_blocs_extra:
+            for b in ir_blocs_extra:
+                b.lines = [instr] * len(b.irs)
+            ir_blocks_all += ir_blocs_extra
+            irb_cur = None
+        return irb_cur
+
+    def add_bloc(self, block, gen_pc_updt = False):
+        """
+        Add a native block to the current IR
+        @block: native assembly block
+        @gen_pc_updt: insert PC update effects between instructions
+        """
+
+        irb_cur = None
+        ir_blocks_all = []
+        for instr in block.lines:
+            if irb_cur is None:
+                label = self.get_instr_label(instr)
+                irb_cur = irbloc(label, [], [])
+                ir_blocks_all.append(irb_cur)
+            irb_cur = self.add_instr_to_irblock(block, instr, irb_cur,
+                                                ir_blocks_all, gen_pc_updt)
+        self.post_add_bloc(block, ir_blocks_all)
+        return ir_blocks_all
 
     def expr_fix_regs_for_mode(self, e, *args, **kwargs):
         return e