about summary refs log tree commit diff stats
path: root/src/miasm/arch/arm/lifter_model_call.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/miasm/arch/arm/lifter_model_call.py')
-rw-r--r--src/miasm/arch/arm/lifter_model_call.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/miasm/arch/arm/lifter_model_call.py b/src/miasm/arch/arm/lifter_model_call.py
new file mode 100644
index 00000000..9aac74a4
--- /dev/null
+++ b/src/miasm/arch/arm/lifter_model_call.py
@@ -0,0 +1,106 @@
+#-*- coding:utf-8 -*-
+
+from miasm.ir.analysis import LifterModelCall
+from miasm.ir.ir import IRBlock
+from miasm.arch.arm.sem import Lifter_Arml, Lifter_Armtl, Lifter_Armb, Lifter_Armtb, tab_cond
+from miasm.expression.expression import ExprAssign, ExprOp, ExprLoc, ExprCond
+from miasm.ir.ir import AssignBlock
+
+class LifterModelCallArmlBase(Lifter_Arml, LifterModelCall):
+    def __init__(self, loc_db):
+        Lifter_Arml.__init__(self, loc_db)
+        self.ret_reg = self.arch.regs.R0
+
+class LifterModelCallArmbBase(Lifter_Armb, LifterModelCall):
+    def __init__(self, loc_db):
+        Lifter_Armb.__init__(self, loc_db)
+        self.ret_reg = self.arch.regs.R0
+
+
+class LifterModelCallArml(LifterModelCallArmlBase):
+
+    def __init__(self, loc_db):
+        LifterModelCallArmlBase.__init__(self, loc_db)
+        self.ret_reg = self.arch.regs.R0
+
+    def call_effects(self, ad, instr):
+        call_assignblk = AssignBlock(
+            [
+                ExprAssign(
+                    self.ret_reg,
+                    ExprOp(
+                        'call_func_ret',
+                        ad,
+                        self.arch.regs.R0,
+                        self.arch.regs.R1,
+                        self.arch.regs.R2,
+                        self.arch.regs.R3,
+                    )
+                ),
+                ExprAssign(
+                    self.sp,
+                    ExprOp('call_func_stack', ad, self.sp)
+                ),
+            ],
+            instr
+        )
+
+
+        cond = instr.additional_info.cond
+        if cond == 14: # COND_ALWAYS:
+            return [call_assignblk], []
+
+        # Call is a conditional instruction
+        cond = tab_cond[cond]
+
+        loc_next = self.get_next_loc_key(instr)
+        loc_next_expr = ExprLoc(loc_next, 32)
+        loc_do = self.loc_db.add_location()
+        loc_do_expr = ExprLoc(loc_do, 32)
+        dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr)
+
+        call_assignblks = [
+            call_assignblk,
+            AssignBlock([ExprAssign(self.IRDst, loc_next_expr)], instr),
+        ]
+        e_do = IRBlock(self.loc_db, loc_do, call_assignblks)
+        assignblks_out = [
+            AssignBlock([ExprAssign(self.IRDst, dst_cond)], instr)
+        ]
+        return assignblks_out, [e_do]
+
+
+    def get_out_regs(self, _):
+        return set([self.ret_reg, self.sp])
+
+    def sizeof_char(self):
+        return 8
+
+    def sizeof_short(self):
+        return 16
+
+    def sizeof_int(self):
+        return 32
+
+    def sizeof_long(self):
+        return 32
+
+    def sizeof_pointer(self):
+        return 32
+
+class LifterModelCallArmb(LifterModelCallArmbBase, LifterModelCallArml):
+
+    def __init__(self, loc_db):
+        LifterModelCallArmbBase.__init__(self, loc_db)
+        self.ret_reg = self.arch.regs.R0
+
+
+class LifterModelCallArmtl(Lifter_Armtl, LifterModelCallArml):
+    def __init__(self, loc_db):
+        Lifter_Armtl.__init__(self, loc_db)
+        self.ret_reg = self.arch.regs.R0
+
+class LifterModelCallArmtb(LifterModelCallArmtl, Lifter_Armtb, LifterModelCallArmb):
+    def __init__(self, loc_db):
+        Lifter_Armtb.__init__(self, loc_db)
+        self.ret_reg = self.arch.regs.R0